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