djangofan djangofan - 7 months ago 11
Java Question

How do I check both 'instanceof' and also the Generic type of a Java object at runtime?

How do I check both

instanceof
and
isAssignableFrom
of a Java object that uses generics?

If I have this method that checks
instanceof
only, BUT I also want to check that it returns a
Boolean
type as opposed to another type, how would I do this?

public void myMethod(ObjectA<Boolean> object)
{
if ( object instanceof ObjectA ) {
// then do something
}
}

Answer

In your example, the instanceof is unnecessary (unless you wanted to check for null, in which case you should just check for null with ==).

Your method declaration

public void myMethod(ObjectA<Boolean> object)

already enforces that callers can only pass values that are of type ObjectA<Boolean> or assignable to type ObjectA<Boolean>.

In other words, I cannot write code like

ObjectA<Integer> notBoolean = ...;
myMethod(notBoolean);

the compiler will reject it.

Within your method, since the parameter is of type ObjectA<Boolean>, the compiler guarantee is that nothing will get through at runtime that isn't an ObjectA. For example, you won't end up with object holding a reference to a Socket or a NoSuchElementException object.


The exception to all of the above is expressions having a raw type. Don't use raw types. Here's why:

With raw types, a client could potentially write

ObjectA<Integer> notBoolean = ...
ObjectA raw = notBoolean;
myMethod(raw);

and the compiler would forgo the generic type check and allow the invocation (the compiler erases the generic usage in the context of that invocation) .

Your code would presumably then fail at runtime with a ClassCastException when trying something like

public void myMethod(ObjectA<Boolean> object)
{
    Boolean ref = object.get(); // ClassCastException
                                // returns an `Integer` and attempts to assign it to a `Boolean` variable
}

Your object would still hold a reference to a ObjectA instance, but whatever it might wrap will no longer necessarily be a Boolean (I'm assuming ObjectA is some kind of wrapper for a Boolean value here).

This ClassCastException will be more or less equivalent to what you could've thrown anyway.

I wouldn't make a check specifically for this raw usage.