public static <T> T foo(T x, T x2) {
return (T) (x + " " + x2);
}
public static void main(String args[]) {
System.out.println(foo(33, "232"));
}
我知道T会成为参数中传递的类型。 但这里有两种类型。 哪一个是T?
当我调用foo时,为什么编译器不会强迫我使用相同类型的参数?
答案 0 :(得分:16)
这是合法的,因为Integer
和String
具有共同的基本类型。 T
可以是Object
,因此foo(T, T)
会接受任意两个对象。 32
可以自动生成Integer
,Object
。"232"
。 String
是Object
,是一种Integer
。
(正如评论所指出的,对于String
和Serializable
,有一个更接近的公共基类型T
;但原则与编译器解析的基本类型相同<div ui-view="header">
</div>
<div class="clearfix">
</div>
<!-- BEGIN CONTAINER -->
<div class="page-container">
<!-- BEGIN SIDEBAR -->
<div class="page-sidebar-wrapper" ui-view="sidebar">
</div>
<!-- END SIDEBAR -->
<!-- BEGIN CONTENT -->
<div class="page-content-wrapper">
<div class="page-content" ui-view="content">
</div>
</div>
<!-- END CONTENT -->
</div>
至。)
答案 1 :(得分:5)
public static <T> T foo(T x, T x2) {
return (T) (x + " " + x2);
}
应该注意的是,虽然这个编译,但它可能在运行时失败:
int f = foo(1, 2);
将失败Ideone demo,因为该方法会返回String
,而不是Integer
。
它编译,因为类型擦除意味着T
被重写为上限,即Object
。所以:
public static Object foo(Object x, Object x2) {
return (Object) (x + " " + x2);
}
这很好,因为结果是String
,这是Object
的子类型。
我想这只是一个仿制药模型等待赶上你的情况。这就是为什么我会避免混合泛型和显式铸造。