Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't you directly cast type in java?

Tags:

java

android

In the code snippet below, why would lines 1 & 2 be fine and line 3 cause a compile error? Aren't the first two lines functionally equivalent to the third?

Loader loader = getLoaderManager().getLoader(0);
PatientLoader patientLoader = (PatientLoader) loader;
patientLoader = (PatientLoader) getLoaderManager().getLoader(0); // ERROR!

Throws this:

java: somepath/Patient.java:99: inconvertible types
found   : android.content.Loader<java.lang.Object>
required: com.example.package.PatientLoader

PatientLoader indirectly extends Loader<>.

I come from a C# background and in C# this would not be a problem, so maybe I'm missing something about the Java type system.

PatientLoader extends AsyncTaskLoader<Cursor>. And anyone familiar w/ Android SDK would know AsyncTaskLoader<> extends Loader<>.

like image 972
Andrew Young Avatar asked Feb 18 '23 14:02

Andrew Young


1 Answers

It has nothing to do with the placement of the parenthesis. This problem has to do with Generics:

E.g. Compilation failure:

Loader<Object> loader = getLoaderManager().getLoader(0);
PatientLoader ch = (PatientLoader)loader; // Will show compile error (Cannot cast from Loader<Object> to PatienLoader)

But this will compile fine:

Loader<?> loader = getLoaderManager().getLoader(0);
PatientLoader ch = (PatientLoader)loader; // Compiles fine.

The difference is the <Object> generic versus the <?> generic declaration.

The problem is that getLoader(int) is defined to return a Loader<D>. This means that 'getLoaderManager().getLoader()' in the statement below gets interpreted as a Loader<Object> and not a Loader<?>.

PatientLoader ch = (PatientLoader)getLoaderManager().getLoader(0); // Compile error.

I think this is a 'bug' in the SDK. The method getLoader(int) should have been defined to return a Loader<?> and not a Loader<D>.

like image 76
Streets Of Boston Avatar answered Feb 28 '23 01:02

Streets Of Boston