The following snippet does not compile on javac, version 17 (Temurin)
class Instanceof {
static void doesNotWork(Object o) {
if (o == null) {
throw new Error();
} else if (!(o instanceof String s)) {
throw new Error();
}
System.out.println(s); // error here
}
}
It generates this error: cannot find symbol
cannot find symbol
symbol: variable s
location: class Instanceof
However, the following (in my opinion) equivalent variations work: With an explicit else block:
static void doesWork(Object o) {
if (o == null) {
throw new Error();
} else if (!(o instanceof String s)) {
throw new Error();
} else {
System.out.println(s);
}
}
Or without an else:
static void doesWork(Object o) {
if (o == null) {
throw new Error();
}
if (!(o instanceof String s)) {
throw new Error();
}
System.out.println(s);
}
Or with a single if:
static void doesWork(Object o) {
if (o == null || !(o instanceof String s)) {
throw new Error();
}
System.out.println(s);
}
Is this a bug in javac? If yes, should I report this, but where exactly?
The doesNotWork
case is equivalent to this:
static void doesNotWork(Object o) {
if (o == null) {
throw new Error();
} else {
if (!(o instanceof String s)) {
throw new Error();
}
}
System.out.println(s); // error here
}
This makes it more obvious that String s
is inside a block bounded by curly brackets and is therefore out of scope in the same way that this doesn't work either:
static void doesNotWork(Object o) {
{
if (!(o instanceof String s)) {
throw new Error();
}
}
System.out.println(s); // error here
}
In the case where it does work, with the println inside the else, it's equivalent to this:
if (o == null) {
throw new Error();
} else {
if (!(o instanceof String s)) {
throw new Error();
} else {
System.out.println(s);
}
}
Which shows the println being in scope.
The relevant bug ticket has been created in the OpenJdk Jira. It is marked as reproduceable so most probably will be handled as bug, and fixed.
Here is the aforementioned ticket so we can trace the progress.
Edit: Seems that this issue is going to affect JDK 20 as well. Resolution is going to take some time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With