当我发现以下代码在没有警告的情况下编译并显示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");
    }
}

我预期会有编译错误。

编译该代码是否有原因?

确保参数具有相同类型的正确方法是什么?

编辑:有界类型参数呢?我能想到的最好的是:
private static <T, U extends T> void method(T arg1, U arg2) {
    System.out.println(arg1.getClass().getSimpleName());
    System.out.println(arg2.getClass().getSimpleName());
}

不幸的是,java不允许循环约束。 <T extends U, U extends T>无法编译。这是死胡同吗?

最佳答案

之所以进行编译,是因为Java将推断传入的参数的最特定父类(super class)型,在本例中为Object Serializable & Comparable<? extends Serializable & Comparable<? extends Comparable<?>>>,将1装箱到Integer并将"1"作为String传递。

没有泛型:

private static void method(Number arg1, Number arg2) {

即使没有泛型,您也可以传递IntegerDouble

仅当所涉及的类型是final时,才可以在没有泛型的情况下执行此操作:
private static void method(String arg1, String arg2) {
    // Yes, they're both Strings, guaranteed.

我可以考虑使用泛型的一种极端情况,以确保它们是准确的类型。如果您有一个final类,并设置了一个上限,则可以将其限制为同一类。
public <T extends MyFinalClass> void method(T arg1, T arg2) {
    // Yes, they're both MyFinalClasses
}

但是,如果没有泛型,您可以做同样的事情。
public void method(MyFinalClass arg1, MyFinalClass arg2) {
    // Yes, they're both MyFinalClasses
}

关于java - 如何在Java中编写一个采用两个相同类型参数的通用方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26538980/

10-11 14:29
查看更多