0

Why do I need to cast the return of obj.getClass() to a Class<T> type when obj has type T? This also generates a warning, which I have silenced. But I feel like this shouldn't be necessary. What's going on here?

public class DataSerialization<T> {
    private T deserializedObject;
    private Class<T> classObject;
    private String serializedObject = null;

    private static final Gson gson = new Gson();

    @SuppressWarnings("unchecked")
    public DataSerialization(T obj) {
        this.deserializedObject = obj;
        this.classObject = (Class<T>) obj.getClass();
    }

    // ...
}   
boshea
  • 115
  • 2
  • 6

1 Answers1

-1

Simply put, it's because the getClass method returns Class<?>, no matter what type of class the object actually is. Even though the reference of type Class<?> is, in this instance, pointing to an object of type Class<T>, the method signature defines the return type as Class<?>, so that is what the compiler is expecting back.

To the compiler, you are casting a Class<?> to a Class<T>, and that flags a warning because there is no way to ensure, by return type alone, that this is the case.

Zircon
  • 4,677
  • 15
  • 32
  • Thanks, that explains it. Is it reasonable to cast this to Class here, since it will always be correct? I don't like suppressing warnings because it usually means that I am doing something wrong, but I just can't think of a case where this won't be correct. – boshea Jun 14 '16 at 20:51
  • I suppose it is reasonable, though I recommend you look at this answer for ideas of how you can get around having to use a "T.class" sort of object. http://stackoverflow.com/a/3437930/4793951 – Zircon Jun 14 '16 at 20:56
  • 1
    @boshea what makes you think it will "always be correct"? Why don't you think `deserializedObject` could be a subtype of `T`? – Louis Wasserman Jun 14 '16 at 21:14
  • That is a good point, although for the purposes of my application, it will still behave correctly. I have simplified this example a bit for brevity, but the objects that will be passed to this class are internal to the application and will not be subclassed (except in tests). – boshea Jun 14 '16 at 21:22
  • "it's because the getClass method returns Class>, no matter what type of class the object actually is." That's not true. `someExpr.getClass()` has the type `Class extends |X|>` where `|X|` is the erasure of the static type of `someExpr`. – newacct Jun 15 '16 at 19:44