In Java 19, I'm trying to use instanceof
pattern matching inside an assert
statement.
I would expect the matched type would be available after the statement, but the Java compiler does not recognize the new variable.
We create a variable Object obj
, and we cannot know whether it contains an Integer
or a String
.
We pass the variable to two test methods.
public class AssertPatternMatching {
public static void main(String[] args) {
Object obj = args.length == 0 ? Integer.valueOf(42) : "Hello";
afterAssert(obj);
insideMessage(obj);
}
In method afterAssert()
, we assert that obj
is a String
, and bind the string to the new variable str
via instanceof
pattern matching.
I would expect str
to be known and usable in the next line.
However, the compiler does not know symbol str
.
private static void afterAssert(Object obj) {
assert obj instanceof String str;
str.length(); // javac: cannot find symbol variable str
}
In method insideMessage()
, we use a convoluted assert
statement to check that obj
is not a String
. If it would be, the assertion fails, and we can provide a message.
As the instanceof
check is negated, pattern matched str
variable should be available for the error message.
However, the compiler again does not know symbol str
.
private static void insideMessage(Object obj) {
assert !(obj instanceof String str) : "Is a string: " + str.length();
// line above: javac: cannot find symbol variable str
obj.hashCode();
}
It works if we replace assert
statements with if
:
private static void afterAssertIf(Object obj) {
if(obj instanceof String str) {
str.length();
} else {
throw new AssertionError();
}
}
private static void insideMessageIf(Object obj) {
if (!(obj instanceof String str)) {
obj.hashCode();
} else {
throw new AssertionError("Is a string: "+ str.length());
}
}
The insideMessage() example is really an edge case, so I understand it's not supported. I would have expected afterAssert() to work, however. Is this a deliberate design choice or a bug? If deliberate, what's the rationale?
Complete code at https://gist.github.com/enikao/57bb1b10ce3126494ec4baa2bc7db2df