Issues with generic type detection of SAM types implemented using lambdas
Remi Forax
forax at univ-mlv.fr
Wed Jan 18 19:02:00 UTC 2017
Hi Oliver,
sorry for not responding earlier,
not having the generic type information was something discussed by the lambda export group, and i'm sure you can also find several threads about that subject on lambda-dev.
There are two reasons to not generate the generic info at runtime:
- these info are used to enable separate compilation, because of the erasure, the argument of the parameterized types is lost, so at the method boundary, the compiler has to keep the generic information to enable separate compilation. At runtime, when the class that hosts a lambda is generated, there is no need for such information.
- a lambda at runtime should be as lightweight as possible (at least for non serializable lambdas), so the spec allows to have several lambdas that share the same class at runtime, in that context having one generic information for several lambdas make no sense.
regards,
Rémi
----- Mail original -----
> De: "Oliver Gierke" <ogierke at pivotal.io>
> À: compiler-dev at openjdk.java.net
> Envoyé: Mercredi 18 Janvier 2017 19:06:30
> Objet: Re: Issues with generic type detection of SAM types implemented using lambdas
> Hi again,
>
> didn't get much response but it looks like there are some improvements for
> lambdas planned for at least JDK10 [0]. Is what I asked for below maybe a
> candidate for inclusion into those efforts?
>
> Is there maybe a better place to ask for this?
>
> Cheers,
> Ollie
>
> [0] https://www.infoq.com/news/2017/01/java10-lambda-leftovers
>
>> Am 23.12.2016 um 12:22 schrieb Oliver Gierke <ogierke at pivotal.io>:
>>
>> Hi all,
>>
>> Lambda based implementations of SAM types currently don't support inspecting the
>> type for generic type parameters. This can cause unexpected surprise as some
>> high-level API taking a SAM type as parameter is usually an indicator to users,
>> that they can be used with Lambdas. If the object passed in is then inspected
>> for generic types somewhere down the call stack this causes issues. Handing in
>> a dedicated implementation of the SAM type is a workaround bit I think that's
>> highly confusing and can be a source of errors hard to understand and debug.
>>
>> I've added an example below.
>>
>> Cheers,
>> Ollie
>>
>> public class LambdaTypeDetectionSample {
>>
>> public static void main(String[] args) {
>>
>> Function<Integer, String> lambdaFunction = i -> i.toString();
>> Function<Integer, String> oldschoolFunction = new Function<Integer, String>() {
>>
>> public String apply(Integer t) {
>> return t.toString();
>> }
>> };
>>
>> printTypeArguments(oldschoolFunction);
>>
>> // Yields:
>> // java.util.function.Function<java.lang.Integer, java.lang.String> is a class
>> sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
>> // class java.lang.Integer
>> // class java.lang.String
>>
>> printTypeArguments(lambdaFunction);
>>
>> // Yields:
>> // interface java.util.function.Function is a class java.lang.Class
>> }
>>
>> private static void printTypeArguments(Function<?, ?> function) {
>>
>> Type type = function.getClass().getGenericInterfaces()[0];
>>
>> System.out.println(type + " is a " + type.getClass());
>>
>> if (type instanceof ParameterizedType) {
>>
>> ParameterizedType functionInterface = (ParameterizedType) type;
>> Arrays.stream(functionInterface.getActualTypeArguments()).forEach(System.out::println);
>> }
>> }
> > }
More information about the compiler-dev
mailing list