Java 与数组不兼容的类型。asList()
在下面的示例中,如果列表中有多个类型,它将编译为ok,但如果有一个元素,它将选择一个不再可分配的不同类型Java 与数组不兼容的类型。asList(),java,generics,Java,Generics,在下面的示例中,如果列表中有多个类型,它将编译为ok,但如果有一个元素,它将选择一个不再可分配的不同类型 // compiles fine List<Class<? extends Reference>> list = Arrays.asList(SoftReference.class, WeakReference.class); // but take an element away and it no longer compiles. List<Class<
// compiles fine
List<Class<? extends Reference>> list = Arrays.asList(SoftReference.class, WeakReference.class);
// but take an element away and it no longer compiles.
List<Class<? extends Reference>> list2 = Arrays.asList(WeakReference.class);
// without giving the specific type desired.
List<Class<? extends Reference>> list3 = Arrays.<Class<? extends Reference>>asList(WeakReference.class);
//编译得很好
列出有趣的问题。我想是这样的。当有两个类似于show的元素时,asList
的返回类型是所有参数中最具体的类型,在第一个示例中是List
。这是与列表兼容的作业这很有趣:
where INT#1 is an intersection type:
INT#1 extends AbstractList,Cloneable,Serializable
也许这就是(某些)问题的原因
元素的相交类型可能不是唯一确定的。当您声明自己的列表时,数组的交集类型被确定为list
使用数组时。对这种行为有两个部分的解释:
右手边的类型如何随着参数的变化而变化
为什么某些RHS类型与LHS类型不兼容
1.右手边
asList
的签名为
<T> List<T> asList(T... a)
及
asList(WeakReference.class、SoftReference.class)
->列表考虑
// ok
List<Object> list3 = Arrays.asList(new Object(), new String());
// fail
List<Object> list4 = Arrays.asList(new String());
现在可以对它们进行编译:
List<Object> list4 = toList(new String());
List<Class<? extends Reference>> list = toList(SoftReference.class, WeakReference.class);
List<Class<? extends Reference>> list2 = toList(WeakReference.class);
否则就不行了
void bar(List<Class<? extends Reference>> list){...}
bar( toList(WeakReference.class) ); // fail; R not inferred
void条(列表我认为jdk<7中的编译器要求语句的两部分具有相同的声明。也不是100%确定这是导致问题的原因!!我正在使用Java 7 update 9。然后,我认为您要么在语句的两侧添加相同的声明,要么在第二部分中根本不声明它。@mamdouhalramadan I ag这是我发现的一种变通方法。我很想知道为什么隐式铸造的规则在不同的情况下会有所不同。所有这些情况对我来说都是有意义的,我仍然看不到你想要在工作和非工作情况之间造成的紧张。Class
is-not-aClass@PeterLawrey-哦,错了,我是说“协变”。更新了答案。在我看来,隐式强制转换的规则在不同的情况下是不同的。一定有某种逻辑说,可以用asList强制转换一种方式,但不能用赋值。@PeterLawrey-计算交集(编译器只需调用asList
)从来都不是问题——最坏的情况下,你最终得到的是Object
。不过,毫不奇怪,赋值语句中解析泛型的规则与方法调用的规则不同。或者我误解了你的观点了吗?@PeterLawrey-我的措辞是错误的。规则相同,但情况不同,因此规则适用。每个实际参数都被分配给一个参数,该参数是所有实际参数的交集类型。根据交集类型的定义,这几乎不会导致问题。另一方面,赋值语句将交集类型分配给代码指定的泛型类型。这时n可能是个问题(在这种情况下,因为泛型类型不是协变的).这种解释在几个方面是错误的:首先,List
的赋值与List+1兼容,我同意这就是为什么我以限制类型交叉的方式创建了虚拟MyList。+1,这是正确答案。关键在JLS§15.12.2.8的第一行:如果该方法的任何类型参数不是从实际参数的类型推断出来的,那么现在将按如下方式推断它们……”因为在Arrays.asList()的情况下,返回列表的类型是从实际参数推断出来的
,上下文推断的规则不适用。您仍然需要将@SuppressWarnings(“unchecked”)
添加到toList
方法中。没有它,我将为varargs参数创建未经检查的泛型数组
警告。列表4=toList(新字符串());
无法编译(不兼容类型)。请修正您的答案。您的列表
方法有问题。从数组返回的列表
。asList
由传入的数组支持。如果将对象
放入列表中,您有一个列表
,它会引发数组异常
。请参阅。
where INT#1 is an intersection type:
INT#1 extends AbstractList,Cloneable,Serializable
List<Class<? extends Reference>> list2 = Arrays.asList(WeakReference.class);
List<Class<? extends Reference>> list3 = Arrays.<Class<? extends Reference>>asList(WeakReference.class);
<T> List<T> asList(T... a)
asList(WeakReference.class) -> List<Class<WeakReference>>
asList(WeakReference.class, SoftReference.class)
-> List<Class<? extends Reference>>
List<Class<WeakReference>> lw = new ArrayList<>();
List<Class<? extends Reference>> lq = lw;
lq.add(PhantomReference.class);
// ok
List<Object> list3 = Arrays.asList(new Object(), new String());
// fail
List<Object> list4 = Arrays.asList(new String());
public static <R, T extends R> List<R> toList(T... elements)
{
return Arrays.asList((R[])elements);
}
List<Object> list4 = toList(new String());
List<Class<? extends Reference>> list = toList(SoftReference.class, WeakReference.class);
List<Class<? extends Reference>> list2 = toList(WeakReference.class);
List<Class<? extends Reference>> foo()
{
return toList(WeakReference.class); // "subject to assignment conversion"
}
void bar(List<Class<? extends Reference>> list){...}
bar( toList(WeakReference.class) ); // fail; R not inferred