The
pattern matching feature was added as a preview feature in Java14, there are no
further enhancements in Java 15. You can learn more about this here.
References
Previous Next HomeThis blog is primarily focus on Java fundamentals and the libraries built on top of Java programming language. Most of the post are example oriented, hope you have fun in reading my blog....:)
Recently I observed a noticeable behavior of instanceof operator while working with interfaces and classes. Let me explain with an example.
InstanceOfDemo.javapublic class InstanceOfDemo { static interface A{} static class B{} static class C{} public static void main(String args[]) { B obj = new B(); System.out.println(obj instanceof A); System.out.println(obj instanceof B); System.out.println(obj instanceof C); } }
When I try
to compile the above program, I end up in compiler error.
It is because Java does not support multiple class inheritance, so it is known during the compilation that an object of type B cannot be a subtype of C. On the other hand, it is possible that obj can be an instance of interface A.
InstanceOfDemo.javapublic class InstanceOfDemo { static interface A{} static class B{} static class C{} static class D extends B implements A{} public static void main(String args[]) { B obj = new D(); System.out.println(obj instanceof A); } }
You may like
Explain Loop inversion in Java
Check whether I have JDK or JRE in my system
How to check whether string contain only whitespaces or not?
How to call base class method from subclass overriding method?
Java14 enhances the instanceof operator by adding pattern matching functionality. This is added as preview feature in Java14.
For example,
if (obj instanceof String) {
String s = (String) obj;
System.out.println("Length of the string s is " + s.length());
}
In the above snippet we are performing three operations.
a. Checking whether the variable ‘obj’ is instance of String or not.
b. Explicitly type casting obj to String
c. Defining new variable s
Above statement can be written using pattern matching like below.
if (obj instanceof String s) {
System.out.println("Length of the string s is " + s.length());
}
In Java14, the instanceof operator is extended to take a type test pattern instead of just a type. In the code above, the phrase String s is the type test pattern. If ‘obj’ is an instance of String, then it is cast to String and assigned to the binding variable s.
Binding variable ‘s’ scope is limited to the true block and not available outside of it.
if (obj instanceof String s) {
// You can use s here
} else {
// You can't use s here
}
InstanceOfPatternDemo.java
public class InstanceOfPatternDemo {
public static void main(String args[]) {
Object obj = "Hello World";
if (obj instanceof String s) {
System.out.println("Length of the string s is " + s.length());
} else {
System.out.println("obj is not instance of String");
}
}
}
Output
Length of the string s is 11
Scope of binding variable is derived by the semantics
The scope of a binding variable, is determined by the semantics of the containing expressions and statements. For example, in this code:
if (! (obj instanceof String s)) {
// You can't use s here
}
else {
// You can use s here
}
InstanceOfPatternDemo2.java
public class InstanceOfPatternDemo2 {
public static void main(String args[]) {
Object obj = "Hello World";
if (! (obj instanceof String s)) {
System.out.println("obj is not instance of String");
} else {
System.out.println("Length of the string s is " + s.length());
}
}
}
Output
Length of the string s is 11
The scope of binding variable grows as the conditional expression grows.
Example
if ((obj instanceof String s) && s.length() > 10) {
System.out.println("obj is instance of String and length is > 10");
} else if ((obj instanceof String s)){
System.out.println("obj is instance of String and length is <= 10");
}else {
System.out.println("Object is not an instance of String");
}
InstanceOfPatternDemo3.java
public class InstanceOfPatternDemo3 {
public static void main(String args[]) {
Object obj = "Hello World";
if ((obj instanceof String s) && s.length() > 10) {
System.out.println("obj is instance of String and length is > 10");
} else if ((obj instanceof String s)){
System.out.println("obj is instance of String and length is <= 10");
}else {
System.out.println("Object is not an instance of String");
}
}
}
Output
obj is instance of String and length is > 10
How instanceof works when the obj is null?
There is no change in the behavior of instanceof operation when the obj is null. The pattern will only match, and s will only be assigned, if obj is not null.
InstanceOfPatternDemo4.java
public class InstanceOfPatternDemo4 {
public static void main(String args[]) {
Object obj = null;
if ((obj instanceof String s) && s.length() > 10) {
System.out.println("obj is instance of String and length is > 10");
} else if ((obj instanceof String s)){
System.out.println("obj is instance of String and length is <= 10");
}else {
System.out.println("Object is not an instance of String");
}
}
}
Output
Object is not an instance of String
Reference
https://openjdk.java.net/jeps/305
package com.sample.app;
public class App {
public static void main(String[] args) {
String str = null;
Integer i1 = null;
if (str instanceof String) {
System.out.println("str is instance of String");
} else {
System.out.println("str is not instance of String");
}
if (i1 instanceof Integer) {
System.out.println("i1 is instance of Integer");
} else {
System.out.println("i1 is not instance of Integer");
}
}
}