Sorry if this was already explained, but i didn't find similar threads anywhere in web.
Today I opened one project class in IDE and saw an error (red underline), though project was compiled successfully.
So, the code is:
public interface DatasourceImplementation<T extends Entity> {
....
}
public interface Datasource<T extends Entity> {
....
}
public interface DsContext {
@Nullable
<T extends Datasource> T get(String name);
}
And now we call this method like this:
DatasourceImplementation dsImpl = getDsContext().get("dsName");
Idea13 gives me error (incompatible types) - I think that's right.
Idea14 does not show any errors here.
JDK compiles it without errors - that's sad.
Must say, that in our project implementation class of A interface always implements B interface (possibly explains why Idea14 says it is OK), but in my opinion that can't justify this behaviour - because generally I can create class that implements A and doesn't implement B. I want static typization in my code, I do not want to see runtime class cast exceptions.
So, who's wrong here?
Upd. Add a screenshot with real classes (not sure it will explain something more, it's just the same as I described)
Swapping the inappropriate constructor call with an instance of the correct type solves the issue, as shown in Fig. 6(b). Fig. 6 also serves as an example to show how the incompatible types error is, in fact, a generalization of the method X in class Y cannot be applied to given types error explored in [4].
As the two variables have different types, you'll get a compilation error. To fix it, you need to change the type of one of the variables to match the other.
JDK is correct. The declaration promises to return ANY datasource, if it doesnt match there will be only a runtime error. Compiler may show some serious warnings but should compile it. The original developer of your snippet probably intended to avoid an explicit cast on each call.
Different ways on how to fix it depending on the intent:
DataSource<?> get(String name)
: Caller will need to cast to
DatasourceImplementation. <T extends Datasource> T get(Class<T> dsType, String name)
. The called function can check or select the returned type at runtime, e.g. wether to return Impl1 or Impl2.<T extends Entity>' Datasource<T> get(String name)
: This was probably intended. Works as long as DatasourceImplementation doesnt need to know the concrete entity-type. If it does need to know it, then <T extends Entity>' Datasource<T> get(Class<T> entityType, String name)
would be better . If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With