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

时间:2017-05-10 08:36:55

标签: java generics overloading

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

我无法找到有关此主题的任何相关讨论。但是,对不同主题的回答让我有点困惑: - Return Type of Java Generic Methods

根据它们,通用<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

2 个答案:

答案 0 :(得分:14)

在您的第一个示例中,您实际上并未指定类型Program的参数,它是通用的。该类型参数与名为Program的类无关。你可以通过这样的拼写错误获得相同的结果:

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);
    }

}

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

答案 1 :(得分:13)

在第一种情况下,Program是用于该方法的通用参数的名称。它可以是任何名称。重要的是method参数是一个Object,所以当你用Integer参数调用你的方法时,它会使用带Object的版本。

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

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

第二个问题是您已将通用参数命名为具体类型,这令人困惑。更容易看出你是不是那样做。

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");
}

现在很明显,你的论点已经成为一个Program对象,而不仅仅是任何对象。