zoukankan      html  css  js  c++  java
  • Java泛型(7):无界通配符<?>

    无界通配符<?>很容易和原生类型混淆。

    以List为例:

    List表示持有任何Object类型的原生List,其实就等价于List<Object>

    List<?>表示某种具有特定类型的非原生List(同构集合),只是我们不知道它的具体类型是什么,所以我们就不允许往里set数据

    看下面例子:

     1 public class Wildcards {
     2 
     3     // 这里Holder等价于Holder<Object>,Holder<Object>没警告但下面的方法调用时除第一个都会报ERROR,Holder会有警告
     4     static void saveData(Holder holder, Object arg) {
     5         holder.set(arg); // [Warning] Type safety: The method set(Object) belongs to the raw type Holder. References to generic type Holder<T> should be parameterized
     6         Object obj = holder.get();
     7         System.out.println(obj.getClass().getSimpleName() + ": " + obj.toString());
     8     }
     9 
    10     // 因为不知道Holder<?>的具体类型是什么,所以我们就不允许往里set数据
    11     static void saveDataError(Holder<?> holder, Object arg) {
    12         // holder.set(arg); // [Compile Error] The method set(capture#1-of ?) in the type Holder<capture#1-of ?> is not applicable for the arguments (Object)
    13         // holder.set(new Wildcards()); // Same Compile Error
    14         Object obj = holder.get();
    15         System.out.println(obj.getClass().getSimpleName() + ": " + obj.toString());
    16     }
    17 
    18     public static void main(String[] args) {
    19         Holder h1 = new Holder<Long>();
    20         Holder<Long> h2 = new Holder<Long>();
    21         Holder<?> h3 = new Holder<Long>();
    22         Holder<? extends Long> h4 = new Holder<Long>();
    23 
    24         saveData(h1, 1L); // Long: 1
    25         saveData(h2, 2L); // Long: 2
    26         saveData(h3, 3L); // Long: 3
    27         saveData(h4, 4L); // Long: 4
    28 
    29         saveDataError(h1, 5L); // Long: 1
    30         saveDataError(h2, 6L); // Long: 2
    31         saveDataError(h3, 7L); // Long: 3
    32         saveDataError(h4, 8L); // Long: 4
    33     }
    34 }
    35 
    36 class Holder<T> {
    37     private T value;
    38     public Holder() { }
    39     public Holder(T val) { value = val; }
    40     public void set(T val) { value = val; }
    41     public T get() { return value; }
    42     @Override public boolean equals(Object obj) { return value.equals(obj); }
    43 }

    捕获转换技术

    如果向一个使用<?>的方法传递原生类型,那么对于编辑器来说,可能会推断出实际的类型参数,使得这个方法可以调用另一个使用确切类型的的方法。下面是一个例子:

     1 public class CaptureConversion {
     2 
     3     static <T> void getData(Holder<T> holder) {
     4         T t = holder.get();
     5         System.out.println(t.getClass().getSimpleName() + ": " + t);
     6     }
     7 
     8     static void chapterGet(Holder<?> holder) {
     9         getData(holder);
    10     }
    11 
    12     public static void main(String[] args) {
    13         Holder h1 = new Holder<Long>(1L);
    14         chapterGet(h1); // Long: 1
    15     }
    16 }
  • 相关阅读:
    668. Kth Smallest Number in Multiplication Table
    658. Find K Closest Elements
    483. Smallest Good Base
    475. Heaters
    454. 4Sum II
    441. Arranging Coins
    436. Find Right Interval
    410. Split Array Largest Sum
    392. Is Subsequence
    378. Kth Smallest Element in a Sorted Matrix
  • 原文地址:https://www.cnblogs.com/storml/p/8005804.html
Copyright © 2011-2022 走看看