Record implementing Interface returns false when checked using instanceof (spring-boot, Java 19)

3.6k views Asked by At

Code example is below.

I have a Record that implements an Interface. When I check if an object of type Record is an instanceof the Interface, the result is false.

Is there any special Java behavior with the combination of Records/Interfaces/instanceof?

The following example results illustrates the problem. isInstanceOf stays false, but I would expect that the condition and thus the variable evaluates to true.

interface Interface1 {}

record Record1(String foo) implements Interface1 {}

...

Record1 rec1 = new Record1("foo");
boolean isInstanceOf = false;

if (rec1 instanceof Interface1){
    isInstanceOf = true;
}

// isInstanceOf is still false
1

There are 1 answers

0
martinspielmann On BEST ANSWER

Found the root cause to the problem here: ClassCastException when casting to the same class

It is not related to Records or other new Java features.

The problem is caused by Spring Boot, or more specifically, the spring-boot-devtools dependency present in my project. It introduces an additional class loader to the project. When a class is loaded by different class loaders, they will not be treated as of the same class, although, their canonical class name is in fact the same.

In the linked question this led to ClassCastExceptions which look confusing, like:

com.pack.Class1 cannot be cast to com.pack.Class1

In addition to the failing class casts described in the linked question, the wrong result of the instanceof operator is another symptom of the underlying class loader problem.

However, in both cases, the solution is to remove the spring-boot-devtools dependency or configure it specifically to your needs, see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-devtools-customizing-classload