-1

I am trying to understand the difference between static and non-static generic methods in Java:

public class Pair<K, V> {

private K key;
private V value;


//the type of the _this_ object and the argument should be the same (just like in scompare)?    
public <X, Y> boolean compare(Pair<X, Y> p2) {
    return key.equals(key) && value.equals(value);
}



public static <N, M> boolean scompare(Pair<N, M> v1, Pair<N, M> v2) {
    return v1.key.equals(v2.key) && v1.value.equals(v2.value);

}
}

Other than the fact that scompare is static, the behavior should not be different. What I find strange is the following:

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, Integer> e1 = new Pair<>(4, 3);


//causes compile-time error (as it should)    
System.out.println("e1 scompare p1: " + Pair.scompare(e1, p1));

//no compile-time error --- why?
System.out.println("e1 compare p1: " + e1.compare(p1)); 

The compile-time error is that one argument is of type Pair<Integer,Integer> and the other is of type Pair<Integer,String>.

So my question is: why does e1.compare(p1) not cause a compile-time error?

Files for this MWE:

Pair.java: https://pastebin.com/rmY9M0gk

D1.java: https://pastebin.com/1MpvPXBC

[Platform: javac 1.8.0_151 openjdk version "1.8.0_151"]

fhussain
  • 1
  • 1

2 Answers2

3
public <X, Y> boolean compare(Pair<X, Y> p2) {
    return key.equals(key) && value.equals(value);
}

should be

public boolean compare(Pair<K, V> p2) {
    return key.equals(key) && value.equals(value);
}

...if you want it to fail to compile. As it stands, your compare method is written to accept any Pair at all.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • And the name of the method could use some polishing too. – Bohemian Dec 20 '17 at 21:27
  • Ah yes, I get it now. In the case of `e1`, both type parameters `K` & `V` get the argument `Integer`. This leaves `X`, `Y` to be bound to any reference type at all, resulting in any `Pair` being legal. Thank you. – fhussain Dec 21 '17 at 15:54
1

In instance method you compare this Pair object which is of types K,V with another Pair object of types X, Y.

So, it is fine: you have Pair<Integer, String> p1 (K=Integer, V=String) and you call to compare with Pair<Integer, Integer> e1 (X=Integer, Y=Integer)

But for static method there are no K and V types. You defined only N and M and explicitly defined that both parameters must be N,M types. And you do not have it since for p1 N=Integer and M=String while for e1 N=Integer and M=Integer.

To make generic static method to compare Pair objects of any classes you have to define all types for both parameters: as

public static <N, M,P,T> boolean scompare(Pair<N, M> v1, Pair<P, T> v2)

BTW: key.equals(key) && value.equals(value); -this does not make any sense. Did you mean key.equals(p2.key) && value.equals(p2.value); ?

Vadim
  • 4,027
  • 2
  • 10
  • 26