当我注意到以下代码编译时没有警告和打印时,我感到非常惊讶Integer / String:
public final class GenericsTest {
private static <T> void method(T arg1, T arg2) {
System.out.println(arg1.getClass().getSimpleName());
System.out.println(arg2.getClass().getSimpleName());
}
public static void main(String[] args) {
method(1, "1");
}
}
Run Code Online (Sandbox Code Playgroud)
我预计会出现编译错误.
这段代码编译的原因是什么?
确保参数具有相同类型的正确方法是什么?
编辑:有界类型参数怎么样?我能想到的最好的是:
private static <T, U extends T> void method(T arg1, U arg2) {
System.out.println(arg1.getClass().getSimpleName());
System.out.println(arg2.getClass().getSimpleName());
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,java不允许循环约束.<T extends U, U extends T>不编译.这是死路一条吗?
这个编译的原因是因为Java会推断传入的参数的最具体的超类型,在这种情况下,在装箱后传递并作为传递.ObjectSerializable & Comparable<? extends Serializable & Comparable<? extends Comparable<?>>>1Integer"1"String
没有泛型:
private static void method(Number arg1, Number arg2) {
Run Code Online (Sandbox Code Playgroud)
即使没有泛型,你也可以传入一个Integer和一个Double.
只有当问题的类型是final你可以这样做,没有泛型:
private static void method(String arg1, String arg2) {
// Yes, they're both Strings, guaranteed.
Run Code Online (Sandbox Code Playgroud)
我可以想到一个带有泛型的边缘情况,以确保它们是确切的类型.如果你有一个final类,并且你设置了一个上限,那么你可以将它限制在同一个类.
public <T extends MyFinalClass> void method(T arg1, T arg2) {
// Yes, they're both MyFinalClasses
}
Run Code Online (Sandbox Code Playgroud)
但是,如果没有泛型,你可以做同样的事情.
public void method(MyFinalClass arg1, MyFinalClass arg2) {
// Yes, they're both MyFinalClasses
}
Run Code Online (Sandbox Code Playgroud)
您可以添加该类作为附加参数。
private static <T> void method(T arg1, T arg2, Class<T> type) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在您必须指定通用类型。
您仍然可以调用,method(1, "1", Object.class);但至少您明确了常见类型。
| 归档时间: |
|
| 查看次数: |
2076 次 |
| 最近记录: |