Java中的泛型如何用于以下程序?

2022-09-02 12:54:35
public class Program {

    private static <Program> void foo(Program x){
        System.out.println(x+"-->1");
    }

    private static void foo(final int i){
        System.out.println(i+"-->2");
    }

    public static void main(String[] args) {
        Integer i = 10;
        foo(i);
    }

}

输出为:

10-->1

我无法找到有关此主题的任何相关讨论。但是,另一个主题的答案让我有点困惑:- Java泛型方法的返回类型

根据他们的说法,泛型与返回类型无关,但在我的情况下,如果我对下面的程序稍作更改,那么输出就不同了。<Program>

public class Program {

    private static <Integer> void foo(Program x){
        System.out.println(x+"-->1");
    }

    private static void foo(final int i){
        System.out.println(i+"-->2");
    }

    public static void main(String[] args) {
        Integer i = 10;
        foo(i);
    }

}

输出:

10-->2

我使用的是 JDK1.7


答案 1

在第一个示例中,您实际上并没有指定类型的参数,它是一个泛型。该类型参数与名为 的类无关。通过像这样拼写错误,您将获得相同的结果:ProgramProgram

public class Program {

    private static <Programmmm> void foo(Programmmm x){
        System.out.println(x+"-->1");
    }

    private static void foo(final int i){
        System.out.println(i+"-->2");
    }

    public static void main(String[] args) {
        Integer i = 10;
        foo(i);
    }

}

但是,在第二个示例中,该参数实际上是类型的,因此在调用 as 时它不匹配,并且您从第二个方法获得结果。Programfoo(10);


答案 2

在第一种情况下,是用于方法的泛型参数的名称。它可以是任何名称。重要的是方法参数是一个 Object,因此当您使用 Integer 参数调用方法时,它使用采用 Object 的版本。Program

在第二种情况下,泛型参数被命名(不要这样做),但方法采用的参数是程序。因此,通过使用整数调用它,不存在有效或整数版本,因此它会取消对值的装箱。IntegerObject

方法重载而言,它描述了解决重载的顺序。这将告诉您为什么第一个版本使用方法而不是方法。Objectint

第二个问题是,您已经将泛型参数命名为具体类型,这令人困惑。如果您不这样做,就更容易看到。

private static <T> void foo(T x){
    System.out.println(x+"-->1");
}

现在它更清楚了,是一个参数化的参数。在您的第二个版本中,T

private static <T> void foo(Program x){
    System.out.println(x+"-->1");
}

现在很清楚,你的参数必须是一个程序对象,而不仅仅是任何对象。