I’m usually a C# developer, new to Java and I’m trying to setup some code using Generics. My Demo code looks like this:
// Main.java
public static void main(String[] args) {
MyBase my = getMeStuff();
System.out.println(my.getSomething());
}
private static <T extends MyBase> T getMeStuff(){
return new MyDerived(123);
}
// MyBase/MyDerived.java
public class MyBase {
private final int something;
protected MyBase(int something) { this.something = something; }
public int getSomething() { return something; }
}
public class MyDerived extends MyBase {
public MyDerived(int something) { super(something); }
}
This fails to compile:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from x.MyDerived to T
at x.Main.getMeStuff(Main.java:14)
at x.Main.main(Main.java:9)
As said, I’m usually a C# Developer, so the code looks good at first glance. I can “resolve” this error by changing getMeStuff to add a cast to (T), but is that cast really necessary? It smells a bit, like I’ve forgotten something?
The problem is that the return type can be anything that derives from MyBase and you’ve specifically typed it to MyDerived, which doesn’t even work in C# without a cast. The caller could have specified SomeOtherDerived instead, which also derives from MyBase but has nothing to do with MyDerived.
It’s also important to note that, even with a cast, this is a very bad thing and can easily result in runtime exceptions when called with any type that’s not explicitly provided. This also goes against the concept of generics by nailing down very specific types in what should be a generalized situation.