ワイルドカード(Wildcard)とは、型パラメータを疑問符を用いて表現し、[未知の型]の[型制約]を表現する方法です。
ジェネリックはデータ型をパラメータとして定義し、使用時に特定の型を指定できます。ただし、使用時に特定の型を判断できない場合は、ワイルドカードを使用して解決する必要があります。
抽象的に言えば、ジェネリック型は共分散をサポートしていないため、ジェネリック型を共分散にするためにワイルドカードが導入されます。
2 つの例を通してワイルドカードの役割を探ってみましょう。
ArrayList<Object> list_obj = null; ArrayList<String> list_str = new ArrayList<String>(); // ArrayList 的元素支持 String -> Object 的强制转换list_str.add("hello"); System.out.println((Object)list_str.get(0));// 编译错误,泛型不支持协变list_obj = list_str;
コードを観察すると、次のことがわかります。
String は Object のサブクラスであるため、ArrayList に格納されている要素は String -> Object への上方変換をサポートしています。
ジェネリックは共分散をサポートしていないため、ArrayList のパラメーターの型を String -> Object に変換するとコンパイル エラーが発生しました。
ArrayList<String> list_str = new ArrayList<String>(); list_str.add("hello"); ArrayList<Integer> list_int = new ArrayList<Integer>(); list_int.add(100); ArrayList<?> list = null; list = list_str; System.out.println(list.get(0)); // hellolist = list_int; System.out.println(list.get(0)); // 100//编译错误list.add("hello"); list.add(100);
コードを観察して次の点を見つけます:
ワイルドカードを使用すると、ジェネリックが共分散をサポートしないという制限が解決され、あらゆるタイプの変換を受け入れることができます。
しかし同時に、あらゆるタイプのオブジェクトを追加する権利も失います。
ワイルドカードには 3 つの形式があります。つまり、
//1、无限定通配符 Demo<?>//2、上边界限定通配符 Demo< ? extends Number> //3、下边界限定通配符 Demo< ? super Number>
次の例を確認してください。継承関係を持つ 3 つのクラスが定義されています。 > 労働者。
class Person{ void print(){ } } class Man extends Person{ void paly(){ } } class Worker extends Man{ void say(){ } }public class Test { public static void main(String[] args) { // 创建了三个 ArrayList 数组 ArrayList<Person> personList = new ArrayList<Person>(); ArrayList<Man> manList= new ArrayList<Man>(); ArrayList<Worker> workerList = new ArrayList<Worker>(); // 限定了上界, ? 代表 Man 以及继承 Man 的类 ArrayList<? extends Man> list = null; list = manList; list = workerList; // 编译错误,因为 Person 是 Man 的父类 list = personList; // 编译错误,因为使用了通配符就不能添加对象 list.add(new Man()); list.add(new Worker()); for(Man man : list){ man.print(); man.paly(); } for(Person per : list){ per.print(); } // 编译错误,因为 ? 也可以代表 Man // 从继承我们可以知道 Worker 肯定是 Man,但 Man 不一定是 Worker。 // for(Worker worker : list); } }
// 省略相同代码...public class Test { public static void main(String[] args) { ArrayList<Person> personList = new ArrayList<Person>(); ArrayList<Man> manList= new ArrayList<Man>(); ArrayList<Worker> workList = new ArrayList<Worker>(); // 限定了下届, ? 代表 Man 以及 Man 的父类 ArrayList<? super Man> list = null; list = personList; list = manList; // 编译错误,因为 Worker 是 Man 的子类 list = workList; // 编译错误,无法确定其父类对象 // Person 继承子 Cell 类,那么用 Person 遍历就是错误的 // for(Man man : list); // for(Person per : list); // 因为 Object 是所有类的根类,所以可以用Object来遍历 // for(Object obj : list); } }
// 省略相同代码...public class Test { public static void main(String[] args) { ArrayList<Person> personList = new ArrayList<Person>(); ArrayList<Man> manList= new ArrayList<Man>(); ArrayList<Worker> workList = new ArrayList<Worker>(); //无边界通配符 ArrayList<?> list = null; //可以代表一切类型 list = personList; list = manList; list = workList; //为了避免类型混淆,只允许使用 Object 遍历 for(Object obj : list); } }
上記は、12. Java の基礎 - ワイルドカードの内容です。詳細については、PHP 中国語 Web サイトを参照してください。 (www.php .cn)!