As far as I can tell, the C ++ compiler creates an instance (implicitly or explicitly) for a given template argument, and at run time we have different functions for each template argument.
There is no such thing as generalization or specialization in Java. For instance,
public class MyClass{
public void <T> method(T t){ }
}
We cannot create and specialize it somehow in C ++
public void <Integer> MyClass::method(Integer t){
}
Instead, type erasure came, so at run time we have one non-generated version of the generic method that you can override.
Take a look at this simple class:
public class Main{
public static void main(String[] args){
Main m = new Main();
m.method(10);
m.methodNumber(10);
m.methodNumberAnd(10);
m.methodNumberAnd2(10);
m.methodInteger(10);
}
public <T> void method(T t){ }
public <T extends Number> void methodNumber(T t){ }
public <T extends Number & java.io.Serializable> void methodNumberAnd(T t){ }
public <T extends java.io.Serializable & java.lang.Comparable<T>> void methodNumberAnd2(T t){ }
public void methodInteger(Integer t){ }
}
And run
javac Main.java
javap -c Main.class
He gives the following:
public class Main {
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class Main
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_1
8: aload_1
9: bipush 10
11: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
14: invokevirtual #5 // Method method:(Ljava/lang/Object;)V
17: aload_1
18: bipush 10
20: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
23: invokevirtual #6 // Method methodNumber:(Ljava/lang/Number;)V
26: aload_1
27: bipush 10
29: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
32: invokevirtual #7 // Method methodNumberAnd:(Ljava/lang/Number;)V
35: aload_1
36: bipush 10
38: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
41: invokevirtual #8 // Method methodNumberAnd2:(Ljava/io/Serializable;)V
44: aload_1
45: bipush 10
47: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
50: invokevirtual #9 // Method methodInteger:(Ljava/lang/Integer;)V
53: return
public <T> void method(T);
Code:
0: return
public <T extends java.lang.Number> void methodNumber(T);
Code:
0: return
public <T extends java.lang.Number & java.io.Serializable> void methodNumberAnd(T);
Code:
0: return
public <T extends java.io.Serializable & java.lang.Comparable<T>> void methodNumberAnd2(T);
Code:
0: return
public void methodInteger(java.lang.Integer);
Code:
0: return
}
Pay attention to the signatures of the compiled methods:
Method method:(Ljava/lang/Object;)V
Method methodNumber:(Ljava/lang/Number;)V
Method methodNumberAnd:(Ljava/lang/Number;)V
Method methodNumberAnd2:(Ljava/io/Serializable;)V
Method methodInteger:(Ljava/lang/Integer;)V
As @Eugene notes, generic types will be erased with the first type binding in the case &
.
source
share