Assuming I have the following classes in an application:
A base class:
public abstract class Animal {}
A subclass
public class Dog extends Animal {
public void bark() {
System.out.println("woof");
}
}
A class from a third party library:
public class ThirdPartyLibrary /* *cough* Hibernate *cough* */{
public List find() {
return new ArrayList() {
// fetched from the db in the actual app of course
{
add(new Dog());
add(new Dog());
add(new Dog());
}
};
}
}
And a utility class:
public class Util {
public <E extends Animal> E findUnique(List<E> animals) {
return animals.isEmpty() ? null : animals.get(0);
}
/**
* @param args
*/
public static void main(String[] args) {
Dog d = new Util().findUnique(new ThirdPartyLibrary().find());
d.bark();
}
}
The eclipse compiler issues the following warnings:
- Type safety: The expression of type List needs unchecked conversion to conform to List
- Type safety: Unchecked invocation findUnique(List) of the generic method findUnique(List) of type Util
But the build fails when compiling with Sun's javac with the error:
incompatible types
[javac] found : Animal
[javac] required: Dog
[javac] Dog d = new Util().findUnique(new ThirdPartyLibrary().find());
[javac] ^
Is there something else I can do to make this code compile in javac, apart from an explicit cast to (List<Dog>)
before the call to findUnique?