Java Generics, how to avoid unchecked assignment warning when using class hierarchy?

I want to use a method using common parameters and return the general result in the class hierarchy.

edit: no SupressWarnings ("unchecked") allowed answer: -)

Here is a sample code illustrating my problem:

import java.util.*; public class GenericQuestion { interface Function<F, R> {R apply(F data);} static class Fruit {int id; String name; Fruit(int id, String name) { this.id = id; this.name = name;} } static class Apple extends Fruit { Apple(int id, String type) { super(id, type); } } static class Pear extends Fruit { Pear(int id, String type) { super(id, type); } } public static void main(String[] args) { List<Apple> apples = Arrays.asList( new Apple(1,"Green"), new Apple(2,"Red") ); List<Pear> pears = Arrays.asList( new Pear(1,"Green"), new Pear(2,"Red") ); Function fruitID = new Function<Fruit, Integer>() { public Integer apply(Fruit data) {return data.id;} }; Map<Integer, Apple> appleMap = mapValues(apples, fruitID); Map<Integer, Pear> pearMap = mapValues(pears, fruitID); } public static <K,V> Map<K,V> mapValues( List<V> values, Function<V,K> function) { Map<K,V> map = new HashMap<K,V>(); for (V v : values) { map.put(function.apply(v), v); } return map; } } 

How to remove the general exception from these calls:

 Map<Integer, Apple> appleMap = mapValues(apples, fruitID); Map<Integer, Pear> pearMap = mapValues(pears, fruitID); 

Bonus question: how to remove a compilation error if I declare the fruitId function as follows:

 Function<Fruit, Integer> fruitID = new Function<Fruit, Integer>() {public Integer apply(Fruit data) {return data.id;}}; 

I am very confused about generics when it deals with hierarchy. Any pointer to a good resource on usage and would be greatly appreciated.

+8
java generics compiler-warnings
source share
1 answer

2 small changes:

 public static void main(final String[] args){ // ... snip // change nr 1: use a generic declaration final Function<Fruit, Integer> fruitID = new Function<Fruit, Integer>(){ @Override public Integer apply(final Fruit data){ return data.id; } }; // ... snip } public static <K, V> Map<K, V> mapValues(final List<V> values, // change nr. 2: use <? super V> instead of <V> final Function<? super V, K> function){ // ... snip } 

For reference:

Get-put principle

+10
source share

All Articles