Objectの変数にStringの変数を代入できるのはcovariantという
Objectの変数にStringの変数を代入できないのはinvariantという
array
arrayはcovariant
arrayの場合、declareしたarrayのtypeではなくarray ref先のarrayのtypeを示している
初期化子を使ってdeclareすると初期化のtypeではなく、declareに指定したtypeになる。
generics
genericsはinvariantなので、
List<Object> l = new ArrayList<string>();は compile-error
List<Object>にadd(String)とすれば、その要素はStringになる。
プログラム的にはList<Object>なので、for(Object o:li)のように取り出す。
new ArrayList<String>();の<String>はプログラム的にも意味をなしていないように見える。
public class Outer {
public static void main(String args[]) {
Object[] o = {"A","B"};
Object[] o1 = {1,1};
Integer[] i = {1,2};
String[] s = {"A","B"};
Object[] o2 = s;
Object[] o3 = i;
System.out.println(s.getClass());
System.out.println(o.getClass());
System.out.println(o1.getClass());
System.out.println(o2.getClass());
System.out.println(o3.getClass());
System.out.println("---------");
List l = new ArrayList<String>();
l.add("A");
l.add(100);
List<Object> l2 = new ArrayList<>();
l2.add("A");
l2.add(100);
Consumer<Object> c = x -> System.out.println(x.getClass());
l.forEach(c);
System.out.println("---------");
l2.forEach(c);
}
}
class [Ljava.lang.String;
class [Ljava.lang.Object;
class [Ljava.lang.Object;
class [Ljava.lang.String;
class [Ljava.lang.Integer;
---------
class java.lang.String
class java.lang.Integer
---------
class java.lang.String
class java.lang.Integer