Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How generics in java works for the following program?

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

}

And the output is:

10-->1

I wasn't able to find any relevant discussion on this topic. However, the answer to a different topic confused me a little:- Return Type of Java Generic Methods

According to them the generic <Program> has nothing to do with return type but in my case if I change a little to this program as below then the output is different.

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

}

Output:

10-->2

I am using JDK1.7

like image 588
Satyaprakash Nayak Avatar asked May 10 '17 08:05

Satyaprakash Nayak


Video Answer


2 Answers

In your first example, You're not actually specifying argument of type Program, it is a generic. That type parameter has nothing to do with your class named Program. You will get same result by making a typo like this:

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

}

However, in your second example, the parameter is literally of type Program and so it doesn't match when called as foo(10); and you get result from second method.

like image 170
Raman Sahasi Avatar answered Oct 20 '22 17:10

Raman Sahasi


In the first case, Program is the name of the generic parameter used for the method. It can be any name. The important thing is that the method argument is an Object, so when you call your method with an Integer argument, it uses the version that takes Object.

In the second case the generic parameter is named Integer (don't do this) but the argument the method takes is a Program. So by calling it with an Integer, there is not valid Object or integer version so it unboxes the value.

In terms of method overloading, which describes the order that overloading is resolved. That will tell you why the first version usings the Object method instead of the int method.

The second issue is that you have named your generic parameters concrete types, which is confusing. It is easier to see if you don't do that.

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

Now it is clearer, T is a parameterized argument. In your second version,

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

Now it is clear, your argument has to be a Program object, and not just any object.

like image 33
matt Avatar answered Oct 20 '22 18:10

matt