Skip to content

How to understand Class.isAssignableFrom() in Java

Reading Time: 4 minutes

Java has quite a few ways to compare types of objects. Most well know are:

  • operator instanceof;
  • method Class.isInstance(Object obj);
  • method Class.isAssignableFrom(Class<?> cls).

The logic of the first two can be quite easily inferred based on the names. But the last one needs a bit of thinking to completely interpret it. So how to understand it once and forever?

Before moving to the last method it is important to understand how the previous two are working.

instanceof

This operator is easy to replace by a simple phrase: “… is a …“, which indicates if a concrete object is related to some group. For example, having two classical representatives of inheritance: Shape and Circle, the following assertions are valid:

// shape IS A shape => YES
// as shape belongs to a group of shapes
Assertions.assertThat(new Shape() instanceof Shape).isTrue();

// circle IS A shape => YES
// as circle belongs to a group of shapes
Assertions.assertThat(new Circle() instanceof Shape).isTrue();

// BUT, shape IS A circle => NO
// as shape does not belong to a group of circles, it is vice versa
Assertions.assertThat(new Shape() instanceof Circle).isFalse();

In fact, C# language has an equivalent of this operator, named is.

One more good explanation of the logic of this operator can be like this: Object instanceof Type is true when Object can be assigned to a variable of type Type.

Class.isInstance(Object obj)

This method is pretty similar to the previously explained operator instanceof. The only difference here is the order of participants: now the object acts as an argument, but the logic is the same: Type.isInstance(Object) is true when Object can be assigned to a variable of type Type.

It is quite an easy exercise to replace isInstance with = sign to simplify the statement: Type.isInstance(Object) => Type t = Object.

// Shape shape = new Shape();   // < OK
Assertions.assertThat(Shape.class.isInstance(new Shape())).isTrue();

// Shape shape = new Circle();  // < OK
Assertions.assertThat(Shape.class.isInstance(new Circle())).isTrue();

// Circle circle = new Shape(); // < ERROR
Assertions.assertThat(Circle.class.isInstance(new Shape())).isFalse();

Side note: condition for instanceof is decided during the compile time, whereas for Class.isInstance(Object obj) – runtime.

Class.isAssignableFrom(Class<?> cls)

To understand this method there can be a couple of ways.

Relation to Class.isInstance(Object obj)

In fact, there is a very simple equation exists between current and previous method: Shape.isInstance(circleObj) == Shape.isAssignableFrom(circleObj.getClass()) but only in case when circleObj is not null. The first method accepts the object but the second one – type.

Assignment rule

Method Class.isAssignableFrom(Class<?> cls) can be replaced with another simple phrase: “… can be set with …“, for example:

// Shape variable can be set with a Shape object
// Shape shape = new Shape();   // < OK
Assertions.assertThat(Shape.class.isAssignableFrom(Shape.class)).isTrue();

// Shape variable can be set with a Circle object
// Shape shape = new Circle();  // < OK
Assertions.assertThat(Shape.class.isAssignableFrom(Circle.class)).isTrue();

// Circle variable can NOT be set with a Shape object
// Circle circle = new Shape(); // < ERROR
Assertions.assertThat(Circle.class.isAssignableFrom(Shape.class)).isFalse();

Loading

Published inJava

Be First to Comment

Leave a Reply

We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept