Skip to content

Document Kotlin declaration site variance subtleties #31370

@wilkinsona

Description

@wilkinsona

Affects: 5.3.x

For background, this problem was identified while looking at https://stackoverflow.com/questions/77233335/how-to-register-new-collection-factories-in-spring-boot.

With a Converter implemented in Kotlin for a List to Guava's ImmutableList conversion:

class ListToImmutableListConverter : Converter<List<Any>, ImmutableList<Any>> { override fun convert(source: List<Any>): ImmutableList<Any> = ImmutableList.copyOf(source) }

ResolvableType resolves the first Any to ? and the second to Object:

val type: ResolvableType = ResolvableType.forClass(ListToImmutableListConverter::class.java).`as`(Converter::class.java) println(type) 
org.springframework.core.convert.converter.Converter<java.util.List<?>, com.google.common.collect.ImmutableList<java.lang.Object>> 

Contrastingly, using Java and ? results in both being resolved to ?:

static class ListToImmutableList implements Converter<List<?>, ImmutableList<?>> { @Override public ImmutableList<?> convert(List<?> source) { return ImmutableList.copyOf(source);	} }
ResolvableType type = ResolvableType.forClass(ListToImmutableList.class).as(Converter.class); System.out.println(type); 
org.springframework.core.convert.converter.Converter<java.util.List<?>, com.google.common.collect.ImmutableList<?>> 

Resolving the target type to ImmutableList<Object> rather than ImmutableList<?> is problematic as it prevents the converter from matching a List<String> to ImmutableList<String> conversion.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions