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