如何编写一个在java中采用相同类型的两个参数的泛型方法?

alk*_*edr 8 java generics

当我注意到以下代码编译时没有警告和打印时,我感到非常惊讶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>不编译.这是死路一条吗?

rge*_*man 7

这个编译的原因是因为Java会推断传入的参数的最具体的超类型,在这种情况下,在装箱后传递并作为传递.Object Serializable & 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)


Max*_*ann 5

您可以添加该类作为附加参数。

private static <T> void method(T arg1, T arg2, Class<T> type) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

现在您必须指定通用类型。

您仍然可以调用,method(1, "1", Object.class);但至少您明确了常见类型。