Spring cannot define generic types when using lambda expression instead of anonymous inner class

I play with Spring ConversionServiceby adding a simple converter to convert ZonedDateTime(Java 8) to String:

@Bean
public ConversionServiceFactoryBean conversionServiceFactoryBean() {
    ConversionServiceFactoryBean conversionServiceFactoryBean =
        new ConversionServiceFactoryBean();

    Converter<ZonedDateTime, String> dateTimeConverter =
        new Converter<ZonedDateTime, String>() {
            @Override
            public String convert(ZonedDateTime source) {
                return source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
            }
        };

    conversionServiceFactoryBean.setConverters(
        new HashSet<>(Arrays.asList(dateTimeConverter)));
    return conversionServiceFactoryBean;
}

It works great. But my IDE (IntelliJ) suggests replacing the anonymous inner class with a lambda expression:

Converter<ZonedDateTime, String> dateTimeConverter =
    source -> source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

If I do this, then it no longer works, I get a Spring error message that is unable to determine the generic types:

Caused by: java.lang.IllegalArgumentException: Unable to the determine sourceType <S> and targetType <T> which your Converter<S, T> converts between; declare these generic types.
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.core.convert.support.GenericConversionService.addConverter(GenericConversionService.java:100)
    at org.springframework.core.convert.support.ConversionServiceFactory.registerConverters(ConversionServiceFactory.java:50)
    at org.springframework.context.support.ConversionServiceFactoryBean.afterPropertiesSet(ConversionServiceFactoryBean.java:70)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)

Class, -, -, Class , Spring . Java 8 -? ​​Spring, ​​ Java 8 ?

Spring 4.1.0.RELEASE Java 8.

+7
2

, , .

, JDK , JVM Lambda, , .

Converter<ZonedDateTime, String> dateTimeConverter =
    source -> source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

,

private static java.lang.String com.example.Test.lambda$0(java.time.ZonedDateTime source)  {
    return source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}

. . JLS

U, - , . U; , ClassCastException.

, , .

static . , Spring , -.

,

interface ZonedDateTimeToStringConverter extends Converter<ZonedDateTime, String> {
}

Converter<ZonedDateTime, String> dateTimeConverter = (ZonedDateTimeToStringConverter)
    source -> source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

ZonedDateTimeToStringConverter dateTimeConverter =  source -> source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

public String convert(ZonedDateTime zdt);

Spring .

+6

TypeTools:

Converter<ZonedDateTime, String> converter = source -> source.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
Class<?>[] typeArgs = TypeResolver.resolveRawArguments(Converter.class, converter.getClass());

assert typeArgs[0] == ZonedDateTime.class;
assert typeArgs[1] == String.class;

Oracle/OpenJDK, API sun.reflect.ConstantPool.

. Spring, ( , Spring ).

+1

All Articles