如果我用不同类的对象调用(泛型)varargs方法,我会收到一个有趣的警告:
List<?> result = Arrays.asList("1", 1);
为varargs参数创建了Object&amp; Serializable&amp; Comparable的通用数组
我可以通过强制转换到公共接口或类来消除警告,
List<Serializable> result = asList((Serializable) "1", (Serializable) 1);
但Object&Serializable&Comparable<?>
是什么意思?是否可以在方法签名的泛型类型注释中使用(例如extends
或super
)?
答案 0 :(得分:3)
类Object
以及接口Comparable
和Serializable
是类Integer
和String
共有的超类型。
由于泛型中的类型擦除和数组的协方差,泛型和数组不能很好地相互混合。方法Arrays#asList
采用varargs作为输入,而在Java中,varargs在内部使用数组实现。因此警告。 (您可以在Josh Bloch的Effective Java中详细了解这一点。)
现在回到第二个问题,可以在方法签名中使用<Object & Comparable<Whatever> & Serializable>
来指定类型参数的约束。 (参见this answer。)但是,Java不允许在泛型类型注释中使用此类型。
换句话说,以下内容有效:
public static void <A extends Comparable<A> & Serializable> meth(A a);
但以下不是:
List<Serializable & SomeOtherInterface> list = ...;
答案 1 :(得分:1)
我认为因为所有对象类型都是Serializable和Comparable(String and Integer),然后编译器说数组中的所有元素都将具有Object类型并实现Serializable和Comparable接口。
我怀疑Serializable&amp; Comparable可以在java代码中正常使用,你总是可以正常实现它们并收到相同的警告: - )
public class ComparableAndSerializableClass implements Comparable<ComparableAndSerializableClass>, Serializable{
public static void main(String[] args) {
List<?> result = Arrays.asList( "1", 1, new ComparableAndSerializableClass());
for (Object comp : result) {
System.out.println(comp.getClass());
}
}
@Override
public int compareTo(ComparableAndSerializableClass o) {
return 0;
}
}
答案 2 :(得分:0)
如果你有Foo<...>
这样的通用类型,那么你可以使用辅助方法为你调用Arrays.asList()
:
public static List<Foo<?>> asList( Foo<?> ... foos ) {
return Arrays.asList( foos );
}
Java编译器将为varargs参数创建一个通用数组,然后您可以在调用Arrays.asList()
时安全地使用该数组。如果您希望所有Foo
具有相同的内部类型:
public static <T> List<Foo<T>> asList( Foo<T> ... foos ) {
return Arrays.asList( foos );
}