The reason that this compiles is because Java will infer the most specific supertype of the arguments passed in, in this case, Object
Serializable & Comparable<? extends Serializable & Comparable<? extends Comparable<?>>>
, after 1
is boxed to Integer
and "1"
is passed as a String
.
Without generics:
private static void method(Number arg1, Number arg2) {
Even without generics, you can pass in an Integer
and a Double
.
Only if the type in question is final
can you do this, without generics:
private static void method(String arg1, String arg2) {
// Yes, they're both Strings, guaranteed.
There is one edge case with generics that I can think of to ensure that they are the exact type. If you have a final
class, and you place an upper bound, then you can restrict it to that same class.
public <T extends MyFinalClass> void method(T arg1, T arg2) {
// Yes, they're both MyFinalClasses
}
But then you could do the same thing without generics.
public void method(MyFinalClass arg1, MyFinalClass arg2) {
// Yes, they're both MyFinalClasses
}