[英]Why does this generic java method accept two objects of different type?
此方法应采用两个相同类型的对象,并随机返回其中一个对象:
public static <T> T random(T o1, T o2)
{
return Math.random() < 0.5 ? o1 : o2;
}
现在,为什么编译器接受具有不同类型的两个参数?
random("string1", new Integer(10)); // Compiles without errors
编辑:既然我知道这两个参数都被隐式上升,我想知道为什么编译器在调用以下方法时会抱怨:
public static <T> List<T> randomList(List<T> l1, List<T> l2) {
return Math.random() < 0.5 ? l1 : l2;
}
呼叫:
randomList(new ArrayList<String>(), new ArrayList<Integer>()); // Does not Compile
如果那些ArrayList参数也被上传到Object,为什么这次会给我一个错误?
T
被推断为Object
,并且两个参数都被隐式地向上转换。
因此代码相当于:
Main.<Object>random((Object)"string1", (Object)new Integer(10));
更令人惊讶的是,以下编译:
random("string1", 10);
第二个参数是自动装入Integer
,然后两个参数都被上传到Object
。
T
被推断为String
和Integer
的常见超类型,即
Object & Serializable & Comparable<? extends Object & Serializable & Comparable<? extends ... ...
好吧,没有人需要关心这一点。
您可以在参数类型上添加更多约束
public static <T1,T2 extends T1> T1 random(T1 o1, T2 o2)
在列表示例中,您需要使用通配符来获得类似的效果
public static <T> List<? extends T> randomList(
List<? extends T> l1, List<? extends T> l2)
知道我知道这两个参数都被隐式上升了,我想知道为什么编译器在调用以下方法时会抱怨:
因为即使A
是B
的子类型,如果A和B不同, List<A>
也不是List<B>
的子类型。
因为您没有以安全,通用的方式调用它。 尝试
MyClass.<String>random("string1", new Integer(10));
而你会得到一个编译错误。
或者让编译器推断出类型,你也应该得到一个编译错误:
String s = random("string1", new Integer(10));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.