为什么java中的这个通用代码会编译?

时间:2017-02-09 10:19:54

标签: java

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时,为什么编译器不会强迫我使用相同类型的参数?

2 个答案:

答案 0 :(得分:16)

这是合法的,因为IntegerString具有共同的基本类型。 T可以是Object,因此foo(T, T)会接受任意两个对象。 32可以自动生成IntegerObject"232"StringObject,是一种Integer

(正如评论所指出的,对于StringSerializable,有一个更接近的公共基类型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的子类型。

我想这只是一个仿制药模型等待赶上你的情况。这就是为什么我会避免混合泛型和显式铸造。