6

I have defined the following generic Class , But when I use it on the Class Object it doesn't compile. The constructor wouldn't accept other object

class Pair<T,V> {

    T one;
    V two;


    public Pair(T one, V two) {
        this.one = one;
        this.two = two;
    }


}
public static void main(String[] args) {

    String hamza = "Hamza";
    Integer soufiane = 0;

    Pair<Object,Object> pairOne = new Pair<>(hamza, soufiane);
    Pair<Object,Object> pairTwo = new Pair<Object, Object>(soufiane, hamza);

}

Error message:

incompatible types: Pair<String,Integer> cannot be converted to Pair<Object,Object>

Why did the first one not Compile and the second compile ?

EDIT: It compiled on Java 8

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • It is quite rare that something doesn't compile and the compiler doesn't tell you _why_ it doesn't compile. – Tom Oct 28 '15 at 15:11
  • 1
    i included the error message there! It's the diamond notation and it should compile, at least to my knowledge. Why it forced me to include the template parameters is what i don't understand. – soufiane fahid Oct 28 '15 at 15:14
  • 3
    Well, Generic Types aren't polymorph, so assigning `Pair` to `Pair` doesn't work and Java 7 think it should be `Pair` because you said the passed arguments will tell the type. Java 8 on the other hand is a bit better with "finding" the correct generic type. – Tom Oct 28 '15 at 15:24
  • @Tom The point of the diamond notation is to match the left hand type which I clearly stated as `Pair`, the constructor should take the parameters by casting them to `Object`. I think matching the type by using the constructor isn't the logical thing here. I could have used an empty constructor and then set the members using setters. – soufiane fahid Oct 28 '15 at 15:30
  • 1
    @soufianefahid The point of the diamond is not to "match the left hand type", but simply to infer the type. Java 7 was much more limited in its ability to do this. In the Java 7 case, the type is being inferred from the arguments, not the left hand type. – Paul Boddington Oct 28 '15 at 15:32
  • @soufianefahid *"I could have used an empty constructor and then set the members using setters"* You could, but you didn't. And when you really do that, then you will see, then Java 7 will accept it. – Tom Oct 28 '15 at 15:33
  • @PaulBoddington Thanks! The word infer does make things clearer. – soufiane fahid Oct 28 '15 at 15:35

1 Answers1

3

Your code fail because the java 7 compiler can't find the proper inferred type; on the other hand java 8 would compile and work fine. (tl;dr: java 7 doesn't properly works with all diamonds, this was improved in java 8)

JEP 101: Generalized Target-Type Inference

Smoothly expand the scope of method type-inference to support (i) inference in method context and (ii) inference in chained calls.

Meaning java 8 would be able to determine the type of your call using the diamond operator.

EDIT: Looks like someone beat me to this reponse in the thread and explained it more clearly than me; so take a look !

Community
  • 1
  • 1
Florian
  • 699
  • 1
  • 5
  • 19