Friday, June 12, 2020

Learn Java 13 and 14

1) Multi-line strings as Text Blocks:

2) Improved instanceOf (Pattern matching)

3) Enter Record (Data Class or Tuple)

4) Sealed Interfaces in Java

Multi-line strings as Text Blocks:

Multi-line strings in Java are finally here in the form of Text blocks. It’s available as a preview feature. So you need to use the switches ––enable-preview and ––release 13 or –release 14 while compiling and executing this code.

public class TextBlocks  {
     
public static void main(String[] args) {
       
String message = """
             Corona Alert!!!
                               
             Lockdown for 21 days!
             Stay calm!
        """
;    
       
       
System.out.println(message);
   
}
}

Compile it using

javac ––enable-preview ––release 13 TextBlocks.java

And when you run it java –enable-preview TextBlocks, you get the following output with the formatting preserved. The compiler also works towards removing trailing whitespaces and meaningless indentations.

Improved instanceOf (Pattern matching)

Let’s look at the use of instanceOf keyword in checking for the type of an object during runtime.

class Vehicle {}
       
class Car extends Vehicle {
 
public void drive() {
       
System.out.println("Driving car");
 
}
}

class Bicycle extends Vehicle {
 
public void ride() {}
}

public class InstanceOfKeyword {
 
public static void main(String[] args) {
       
Vehicle vObj = new Car();
       
if(vObj instanceof Car) {
           
Car car = (Car) vObj;
           car
.drive();
       
}
       
else if(vObj instanceOf Bicycle) {
         
Bicycle bike = (Bicycle)vObj;
          bike
.ride();
       
}
 
}
}

What’s frustrating with the above code is the type-cast of the vehicle object to Car or Bicycle after identifying it’s type using instanceof!

Java 14 changes that, by imparting some pattern matching power to instanceOf like this

       Vehicle vObj = new Car();
       
if(vObj instanceof Car car) {
          car
.drive();
       
}
       
else if(vObj instanceOf Bicycle bike) {
          bike
.ride();
       
}

In the new version, instanceOf tests for the type and binds to a variable of the type. In our case car and bike variables are automatically bound to the corresponding Car and Bicycleobjects respectively, eliminating the need to type-cast. Cool. Isn’t it?

The scope of the variables are limited to the if-else blocks

Enter Record (Data Class or Tuple)

Let’s continue with our lessons during this corona lockdown. In the last two posts we discussed textblocks and instanceof in Java 13 and 14.

Say, you have a shopping cart that is a collection of ShoppingItem with id, name, price and quantity members. Building this will involve writing so many lines of code as shown below.

class ShoppingItem {
   
private int id;      
   
private String name;
   
private double price;
   
private int quantity;
       
   
public ShoppingItem(int id, String name, double price, int quantity) {
       
this.id = id;
       
this.name = name;
       
this.price = price;
       
this.quantity = quantity;
   
}
       
   
public int getId() {
       
return id;
   
}
   
public void setId(int id) {
       
this.id = id;
   
}
   
public String getName() {
       
return name;
   
}
   
public void setName(String name) {
       
this.name = name;
   
}
   
public double getPrice() {
       
return price;
   
}
   
public void setPrice(double price) {
       
this.price = price;
   
}
   
public int getQuantity() {
       
return quantity;
   
}
   
public void setQuantity(int quantity) {
       
this.quantity = quantity;
   
}
       
   
public int hashCode() {
       
return id;
   
}
       
   
public boolean equals(Object obj) {
       
if(obj instanceof ShoppingItem item) {
               
return item.id == this.id;
       
}
       
return false;
   
}
   
   
public String toString() {
       
return name;
   
}
}

public class RecordsExample {
   
public static void main(String[] args) {
       
ShoppingItem book = new ShoppingItem(21321, "Programming Java", 12.34, 1);
       
ShoppingItem mobile = new ShoppingItem(21233, "iPhone 11 pro", 999, 1);
       
List<ShoppingItem> cart = Arrays.asList(book, mobile);
        cart
.forEach(System.out::println);
   
}
}

Phew! That’s lot of code for just storing some data

Code-Monkey-Computing-ReadabilityImage source: https://blog.submain.com/evaluate-code-readability/


Enter record

ShoppingItem class can be replaced with just one line code using a record. If you define a class as record with the members, the hashCode(), equals(), toString(), getters/setters are automatically generated for you by the compiler. So the code using record is as shown below.

public class RecordsExample {
   record
ShoppingItem(int id, String name, double price, int quantity) {}
   
public static void main(String[] args) {
       
ShoppingItem book = new ShoppingItem(21321, "Programming Java", 12.34, 1);
       
ShoppingItem mobile = new ShoppingItem(21233, "iPhone 11 pro", 999, 1);
       
List<ShoppingItem> cart = Arrays.asList(book, mobile);
        cart
.forEach(System.out::println);
 
}
}

This one line 
record ShoppingItem(int id, String name, double price, int quantity) {}
does the trick

Record in Java, in short is a data class or a tuple that’s a simple data structure.

Please remember to compile using –enable-preview and –release 14 switches

Sealed Interfaces in Java

In the last three posts we discussed textblocks, instanceof and record types in Java 13 and 14.

In languages like C#, sealed types are equivalent to final classes in Java. The problem with final classes in Java is no other class present in any other library can extend it. It’s tightly packed.
Now, Java is about to introduce a new sealed keyword, for creating sealed interfaces. We can create sealed interfaces and specify the types that can implement the interfaces. So sealed interfaces unlike final types, specify restricted implementations.

sealed interface Animal permits Dog, Cat {}
class Dog implements Animal {}
class Cat implements Animal {}
class Ant implement Animal {} //ERROR

In the code above, Animal is a sealed interface and only Dog and Cat classes can implement it. Ant will not be allowed to implement. So naturally even an anonymous/lambda implementation of Animal is also not possible. 

Therefore the compiler as well as the JVM enforce the implementation of sealed types.



No comments:

Post a Comment