Wytze Wytze - 2 months ago 21
Java Question

Java 8 Stream loses type information

I have the following stream to select objects that match a certain criteria:

protected final Map<String, PropertyMapping> propertyMappings = new LinkedHashMap();

public List<PropertyMapping> getPropertyMappingsByAnnotation(final Class annotation) {
return propertyMappings.values()
.stream()
.filter(pm -> pm.getAnnotation(annotation) != null)
.collect(Collectors.toList());
}


The filter somehow causes the Stream to lose track of the generic type of the stream which causes the collect statement to fail with the following error:

incompatible types: java.lang.Object cannot be converted to java.util.List<PropertyMapping>


If I change the filter to pm -> true for example the stream works again. What causes this behavior and is there a way to avoid this? It probably has something to do with the 'annotation' class that gets passed in. I tried to pass a final modifier to see if that fixes the problem.

This is the signature of the getAnnotation method:

public final <T extends Annotation> T getAnnotation(Class<T> annotationClass)

Answer

The obvious issue I can see is that you are trying to pass a plain Class variable as an argument to a method that expects a Class<T> where <T extends Annotation>. I imagine that the compiler is failing to fully figure that method call out and it's causing the compilation error at the end of the stream chain. If you fix that, your mystery problem might go away.

Something like this:

public <T extends Annotation> List<PropertyMapping> 
    getPropertyMappingsByAnnotation(Class<T> annotation) {