Comparator
Remi Forax
forax at univ-mlv.fr
Wed Jul 24 07:43:27 PDT 2013
On 07/24/2013 12:18 PM, Ali Ebrahimi wrote:
> 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<>();}
yes, that what John said.
And this is important because otherwise people will start using static
methods instead of instance methods,
in fact it's already an issue:
https://github.com/alexruiz/fest-util/blob/master/src/main/java/org/fest/util/Lists.java#L93
It means that the computation of the set of applicable methods needed to
be delayed until the whole expression
is type checked so instead of having a set of applicable methods you
have a 'path' of applicable methods,
i.e. if you have an expression like new Foo<>().bar().baz(), the set of
applicable methods 'bar' depends on
the set of applicable method 'baz'.
Rémi
>
>> 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