Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No compiler error about incompatible casts

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)

enter image description here

like image 580
AdamSkywalker Avatar asked Jan 26 '15 08:01

AdamSkywalker


People also ask

How do I fix incompatible type error?

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].

What is incompatible type error in C?

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.


1 Answers

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:

  1. DataSource<?> get(String name): Caller will need to cast to DatasourceImplementation.
  2. <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.
  3. <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 .
like image 119
Markus Kull Avatar answered Sep 28 '22 08:09

Markus Kull