Comparator

Ali Ebrahimi ali.ebrahimi1781 at gmail.com
Wed Jul 24 03:18:30 PDT 2013


Hi, current inference can guide you to get expected and reasonable results
for each case.

for this purpose I add two new methods.

    public  static <S,T extends Serializable> C<S,T> m(T p){ return new
C<>();}
    public  static <S,T extends Serializable> C<S,T> m(S u){ return new
C<>();}


> class C<S,T extends Serializable> {
>   public C<S,T> m(S arg) { System.out.println("m #1"); return this; }
>   public C<S,T> m(T arg) { System.out.println("m #2"); return this; }
> }
>
> C<String, Integer> c1 = new C<>().m("abc");
>
I think this is almost equivalence to:
C<String, Integer> c1 = new C<TobeInferredS,TobeInferredT>().m("abc");
So in this case method 'm' receives two un-inferred type var from its
receiver.
On the other side, target type for method m is C<String, Integer>.

So in this phase, if we ignore receiver part and reduce problem to this:
C<String, Integer> c1 = m("abc");
Current inference scheme infers T:String & S:String and compile fails, and
this is OK.
So, this case:
C<String, Integer> c1 = new C<>().m("abc");
should fail.
But,

C<Integer, String> c2 = new C<>().m("abc");
>
With the above process
 C<Integer, String> c1 = m("abc");
Current inference scheme infers T:String & S:Integer, So inference engine
can backwards and resolve diamond in new C<>() to new C<String, Integer>()

C<Number, Integer> c3 = new C<>().m(23);
>
With the same process we get: T:Integer & S:Number and compiler is happy.

> C<Integer, Number> c4 = new C<>().m(23);
>
But, for this case, compiler infers T:Integer & S:Integer and fails.

>
>
Other solution: temporarily (copy or clone) class type variables to methods
(and sync them with class counterparts) and utilize from compiler's
powerful generic method inference support.

    static class C<CS,CT extends Serializable> {
        public <S,T extends Serializable> C<S,T> m(S arg) {
System.out.println("m #1"); return (C<S,T>)this; }
        public <S,T extends Serializable> C<S,T> m(T arg) {
System.out.println("m #2"); return (C<S,T>)this; }
    }

So with generic methods inference works forward and backward.

C<String, Integer> c1 = new C<>().m("abc"); //fails
C<Integer, String> c2 = new C<>().m("abc"); //OK
C<Number, Integer> c3 = new C<>().m(23); //Ok
C<Integer, Number> c4 = new C<>().m(23); //fails


Best Regards,
Ali Ebrahimi


More information about the lambda-dev mailing list