Differencebetween Instanceof and Class.Isassignablefrom(...)

What is the difference between instanceof and Class.isAssignableFrom(...)?

When using instanceof, you need to know the class of B at compile time. When using isAssignableFrom() it can be dynamic and change during runtime.

java: Class.isInstance vs Class.isAssignableFrom

clazz.isAssignableFrom(Foo.class) will be true whenever the class represented by the clazz object is a superclass or superinterface of Foo.

clazz.isInstance(obj) will be true whenever the object obj is an instance of the class clazz.

That is:

clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)

is always true so long as clazz and obj are nonnull.

Class#isInstance vs Class#isAssignableFrom

isAssignableFrom also tests whether the type can be converted via an identity conversion or via a widening reference conversion.

    Class<?> cInt = Integer.TYPE;

Long l = new Long(123);

System.out.println(cInt.isInstance(l)); // false
System.out.println(cInt.isAssignableFrom(cInt)); // true

instanceof fails but isInstance() and isAssignableFrom() work?

x instanceof Y only compiles if the compile-time type of x is compatible with Y. For example, the code below doesn't compile because no String is a Number.

String str = "Foo";
System.out.println(str instanceof Number);

In your case, responseClass is a Class, not a ThisClass so

responseClass instanceof Class

compiles, and gives true, whereas

responseClass instanceof ThisClass

doesn't compile. You should use isInstance.

Java isInstance vs instanceOf operator

This is so that I can really flexibly assign the query return type in the actual helper.

There is nothing flexible about the return type of this method

static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) {
if (expectedReturn.isInstance (SomeRelatedClass.class))
return query1;
else
return query2;
}

It will always return an instance of QueryHelper. If you want the return type to be flexible you would need to define it as something like:

static <T> T getQueryHelper (Class<T> expectedReturn) {
}

Now the return type is flexible, because it will depend on the type of the argument

And the real heart of this is that I don't understand the difference between class.isInstance and the instanceOf operator?

The difference is that instanceof does a type-check that is fixed at compile-time, for example:

static boolean isInstance(Object myVar) {
return (myVar instanceof Foo);
}

will always check that myVar is an instance of Foo, whereas

static <T> boolean isInstance(Object myVar, Class<T> expectedType) {
return expectedType.isInstance(myVar);
}

will check that myVar is an instance of expectedType, but expectedType can be a different type each time the method is called

What is the difference between the 'instanceof' and 'in' keywords?

The main difference is that instanceof is a Java keyword, while obj in SomeClass is an equivalent of SomeClass.isCase(obj) method call as you mentioned in your question.

There is one major implication: instanceof cannot be overridden and as Oracle docs says:

The instanceof operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.


Source: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

Class.isCase(obj) is implemented as follows:

/**
* Special 'Case' implementation for Class, which allows testing
* for a certain class in a switch statement.
* For example:
* <pre>switch( obj ) {
* case List :
* // obj is a list
* break;
* case Set :
* // etc
* }</pre>
*
* @param caseValue the case value
* @param switchValue the switch value
* @return true if the switchValue is deemed to be assignable from the given class
* @since 1.0
*/
public static boolean isCase(Class caseValue, Object switchValue) {
if (switchValue instanceof Class) {
Class val = (Class) switchValue;
return caseValue.isAssignableFrom(val);
}
return caseValue.isInstance(switchValue);
}

Source: org/codehaus/groovy/runtime/DefaultGroovyMethods.java#L1121

As you can see based on the source code Groovy's obj in SomeClass is not an alias to instanceof, because it does a bit more. However, there is one important thing worth mentioning - you can override isCase() implementation, but you can't change how instanceof Java keyword behaves. Overriding Class.isCase() may cause some damage to your code if you use it as an alternative to Java's instanceof keyword.

Using instanceof to seperate classes in an ArrayList

I'm not sure what Packable is, but you appear to be confused about a few concepts here.

In java, Packable reference does not represent the Packable concept. It represents a specific instance of Packable (or null).

In other words, given Dog dog, that means dog is some specific dog. Not 'the general concept of a dog'. We know that the specific animal that dog is referring to is, at least, a Dog. It could be Fifi, the neighbour's schnauzer.

instanceof, on the other hand, is about the general concept of things: if (fifi instanceof Dog) is how you're supposed to use it. You're more or less attempting to do the equivalent of if (fifi instanceof rover) which just doesn't make sense. How can one dog be 'an instance' of another? It's not that the answer is 'true' or 'false', but that the very question doesn't even make sense, which is why javac doesn't compile it. It has no idea what this even means.

Java, being java, makes objects of many things. Notably including the very notion of things. Thus, there is the class java.lang.Class, instances of which represent classes. A bit of alice-going-down-the-rabbit-hole thing is happening here: Classes as a concept are also represented as instances of the java.lang.Class class.

A class OBJECT (so, an instance of java.lang.Class) has the .isAssignableFrom method. This in fact takes another j.l.CLass as argument, it's for checking if one type is a subtype of another. In that sense, the question linked is needlessly confusing - you're really looking for the instanceOf method (there is an instanceof language construct, but the j.l.Class class has an isInstance method, which is unrelated, other than that they roughly accomplish the same goal: Check if some INSTANCE is of a type that is equal to, or a subtype of, some TYPE.

This is an example of how to use it:

Class<?> c = Number.class;
Object o = Integer.valueOf(5);
System.out.println(c.isInstance(o));

this is more or less equivalent to:

Object o = Integer.valueOf(5);
System.out.println(o instanceof Number);

Except now the Number part no longer needs to be written at 'write the code' time, you can supply it, say, read it from a parameter. You'd have to, of course, dynamically construct the Class instance. You can do so either by string-lookup, or by getting the actual type of an actual object. For example:

String input = scanner.next(); // user types in "java.lang.Number"
Class<?> c = Class.forName(input);
Object o = Integer.valueOf(5);
System.out.println(c.isInstance(o));

Or:

Object i = Integer.valueOf(5);
Object d = Double.valueOf(10);
Class<?> c = i.getClass(); // will be java.lang.Integer.class
System.out.println(c.isInstance(d)); // false

But doing this latter bit is really dangerous. Often i.getClass() returns some hidden impl detail subtype (java is hierarchical and object oriented, anywhere, say, an ArrayList is needed, someone is free to make a new class: class MyVariantOfArrayList extends ArrayList, and use that - now you write ArrayList foo = getList(), but foo.getClass() doesn't return ArrayList - no, you invoke that method on the object the foo variable points at, so, it'd be MyVariantOfArrayList.class, not ArrayList.class.

It's possible Packable itself represents a type. But then it either needs to also have isInstance and isAssignableFrom and such (and you need to start questioning why you're badly reinventing the wheel here - java.lang.Class already exists!), or it needs a .getRepresentedClass() method. You can't call it .getClass(), as the JVM has already given all objects that method, and it would return Packable.class itself.

Cannot find the Type of class to use with instanceOf

instanceof only works with literal classes, not with Class objects.

Class.isInstance

You must call the isInstance method on Class class. Do not confuse with instanceOf.

 class0.isInstance(rootCause)


Related Topics



Leave a reply



Submit