Java – generic method call
I have this code from "Java - Beginner's Guide - Schildt", Chapter 13:
package com.chapter.thirteen;
public class GenericMethodDemo {
static <T extends Comparable<T>,V extends T> boolean arraysEqual(T[] x,V[] y){
if(x.length != y.length) return false;
for(int i = 0; i < x.length; i++)
if(!x[i].equals(y[i])) return false;
return true;
}
public static void main(String args[]){
Integer [] nums = { 1,3,4,6 };
Integer [] nums2 = { 1,6 };
Integer [] nums3 = { 1,6 };
Integer [] nums4 = { 1,6,7};
Double [] dVals = {1.1,2.2,3.3,4.4};
if(arraysEqual(nums,nums))
System.out.println("nums equal nums");
if(arraysEqual(nums,nums2))
System.out.println("nums equal nums2");
if(arraysEqual(nums,nums3))
System.out.println("nums equal nums3");
if(arraysEqual(nums,nums4))
System.out.println("nums equal nums4");
//Edit:Removed the comments from the below two lines.
if(arraysEqual(nums,dVals))
System.out.println("Nums equal dVals");
}
}
Compilation fails with message – "error: (39,12) Java: arraysequal.genericmethoddemo in method class com.chapter.thirten cannot be applied to the given type; required: T [], v [] found: java.lang.integer [], java.lang. Double [] reason: inference variable t has incompatible boundary equality constraints: java.lang.integer lower bound: V, java.lang.double, java.lang.integer "This is expected
However, when I miss adding parameters to comparable (as shown in the following code), the code compiles and generates the correct results
package com.chapter.thirteen;
public class GenericMethodDemo {
static <T extends Comparable,nums4))
System.out.println("nums equal nums4");
if(arraysEqual(nums,dVals))
System.out.println("Nums equal dVals");
}
}
Can anyone explain why compilation does not fail in the second case? I once expected the compiler to complain that t extends comparable, and V extends t in the second instance?
What's going on?
Solution
The reason is because of PECS rules
When you do this
static <T extends Comparable,V[] y)
You are basically stating that T and V are subtypes of comparable This means that calling arraysequal (integer [], double []) should work because both integer and double implement comparable
However, when you add a generic type to comparable, the contract will be lost,
static <T extends Comparable<T>,V[] y)
Here, double does not implement comparable < integer >, which is the reason for the compiler error
Editor: if your question is why rawtype comparable doesn't give compiler errors, the answer is how generics work
You can also try using number,
static <T extends Number,V[] y)
Rawtypes are not involved here. You can call arrayequals (integer [], double []), which works normally because they are all numbers
