Power node Wanghe SpringBoot study notes - new features of JDK

Table of contents

1. New features of JDK concern

1.1 Build a learning environment

1.2 Useful new features

1.2.1 Java Record

1.2.1.1 See how to use Record

1.2.1.2 Instance Methods 

1.2.1.3 Static Method Static Method

1.2.1.4 Construction method of Record

1.2.1.5 Record and Lombok

1.2.1.6Record implementation interface

1.2.1.7Local Record

1.2.1.8 Nested Records

1.2.1.9 instanceof judges the Record type

1.2.2 Switch

1.2.2.1 Arrow expressions, new case tags

1.2.2.2 Yeild return value

1.2.2.3 Java Record

1.2.3 Text Block

1.2.3.1 Recognizing text blocks

1.2.3.2 Text blocks are the same as ordinary double-quoted strings

1.2.3.3 Blank

1.2.3.4 Text block methods

1.2.3.5 Escape characters

1.2.4 was

1.2.4.1 var declares local variables

1.2.4.2 Use var when using

1.2.5 sealed

1.2.5.1 Sealed Classes

1.2.5.2 Sealed Interface



1. New features of JDK concern

1.1 Build a learning environment

JDK:JDK19

OpenJDK: https://jdk.java.net/19/​​ Liberica JDK: https://bell-sw.com/pages/downloads/​​ , is an OpenJDK distribution, which is cloud-native, Containers are especially optimized.

Maven: build and dependency management, version 3.6 or above

Configure local warehouse and Alibaba Cloud mirror

IDEA2022.3.1Ultimate: the main development tool, I am a 30-day trial version

Database: MySQL 5 or above

Firefox browser: use a relatively new version, the Chinese version.

Text tools: EditPlus, Sublime any.

1.2 Useful new features

JDK8-19 has added many new features. Here we will introduce the new features that are actually commonly used. Including the following aspects:

  • Java Record
  • Switch expression
  • Text Block text block
  • var declares a local variable
  • sealed sealed class

1.2.1 Java Record

The new feature previewed in Java14 is called Record. In Java, Record is a special type of Java class. Can be used to create immutable classes with short syntax. See JEP 395. Jackson 2.12 supports the Record class.

Anytime a Java class is created, a lot of boilerplate code is created, we might do something like this:

  • set and get methods for each field
  • public constructor
  • Override hashCode, toString(), equals() methods

Java Record avoids the above-mentioned boilerplate code, and has the following characteristics:

  • Constructor with all parameters
  • public accessor
  • toString(),hashCode(),equals()
  • No set, get method. Does not follow the bean naming convention
  • The final class cannot inherit from Record, and Record is the final class of a hermit. Otherwise it is the same as normal class
  • Immutable class, create Record by construction
  • final attribute, cannot be modified
  • Instance attributes cannot be declared, static members can be declared

IDEA creates a new Maven project Lesson01-feature

1.2.1.1 See how to use Record

IDEA creates a new Class and selects the class Record 

step1: Create Student Record

public record Student(Integer id,String name,String email,Integer age) { }

step2: Create a Record object

​
public static void main(String[] args) {
Student lisi = new Student(1001, "​​lisi","[email protected]​​",20); 
System.out.println("lisi = " + lisi.toString());
Student zhangsan = new Student(1002, "​​zhangsan","[email protected]​​",20); 

System.out.println("zhangsan = " + zhangsan.toString()); 

System.out.println("lisi.equals(zhangsan) = " + lisi.equals(zhangsan)); 

System.out.println("​​lisi.name​​() = " + ​​lisi.name​​()); 

System.out.println("​​zhangsan.name​​() = " + ​​zhangsan.name​​());
}

Now you can see the console output:

lisi = Student[id=1001, name=lisi, [email protected]​​, age=20] zhangsan = Student[id=1002, name=zhangsan, [email protected]​ ​, age=20] lisi.equals(zhangsan) = false ​lisi.name​ ​() = lisi ​zhangsan.name​ ​() = zhangsan

Record creates a read-only object through the constructor, which can read each property and cannot set new property values. Records are used to create immutable objects while reducing boilerplate code.

Record provides public accessors for each attribute, such as lisi.name​ ()

1.2.1.2 Instance Methods 

Record is a Java class that defines methods like a normal Java class. The method concat is defined below to print out the name and age together. We create a common method concat to concatenate name and age into a string output. 

step1: Create an instance method 

​
public record Student(Integer id,String name,String email,Integer age) {
public String concat(){
return String.format("姓名:%s,年龄是:%d", ​​this.name​​,this.age);
} }

​

step2: call the instance method

public static void main(String[] args) {
Student lisi = new Student(1001, "​​lisi","[email protected]​​",20);
String nameAndAge = lisi.concat();
System.out.println( nameAndAge);
}

Final console output: Name: lisi, age: 20

1.2.1.3 Static Method Static Method

The Record class defines static methods, and the use of static methods is the same as that of ordinary classes.

step1: Create a static method

​
public record Student(Integer id,String name,String email,Integer age) {
public String concat(){
return String.format("姓名:%s,年龄是:%d", ​​this.name​​,this.age);
}
/** 静态方法 */
public static String emailUpperCase(String email){
return Optional.ofNullable(email).orElse("no email").toUpperCase();
} }

​

step2: Test the static method

public static void main(String[] args) {
String emailUpperCase = Student.emailUpperCase("​​[email protected]​​"); System.out.println("emailUpperCase = " + emailUpperCase);
}

1.2.1.4 Construction method of Record

We can add constructors to Record, there are three types of constructors: compact, standard and custom constructors

  • The compact constructor doesn't have any parameters, not even parentheses.
  • The canonical constructor takes all members as parameters
  • The custom construction method is the number of custom parameters

step1: compact and custom construction methods

public record Student(Integer id,String name,String email,Integer age) { /紧凑构造方法/
public Student {
System.out.println("id"+ id );
if( id < 1 ){
throw new RuntimeException("ok");
}
}
/自定义构造方法/
public Student(Integer id, String name) {
this(id, name, null, null);
} }

step2: compile Student.java -> Student.class

​
public record Student(Integer id, String name, String email, Integer age) { /** 紧凑构造方法和规范构造方法合并了 */
public Student(Integer id, String name, String email, Integer age) {
System.out.println("id" + id);
if (id < 1) {
throw new RuntimeException("ok"); } else {
​​this.id​​ = id;
​​this.name​​ = name;
this.email = email;
this.age = age;
}
} public Student(Integer id, String name) {
this(id, name, (String)null, (Integer)null);
} }

​

1.2.1.5 Record and Lombok

Java Records are a great way to create immutable classes and reduce boilerplate code. Lombok is a tool for reducing boilerplate code. The two have superficial overlaps. Some people may say that Java Record will replace Lombok. The two are tools with different purposes.

Lombok provides syntax convenience, and usually pre-installs some code templates, which are automatically executed according to the annotations you add to the class. Such libraries are purely for convenience in implementing POJO classes. By precompiling code. Add the template of the code to the class.

Java Record is a language level, a semantic feature, used for modeling, data aggregation. Simply put, it provides a common data class that acts as a "data carrier" for data transmission between classes and applications.

1.2.1.6Record implementation interface

Java Record can implement interfaces like ordinary classes, and rewrite methods of interfaces.

step1: Create a new interface and define a specification method.

public interface PrintInterface {
/** 输出自定义描述信息 */
void print(); }

step2: Create a new Record implementation interface, rewrite the method of the interface, and implement the business logic related to the current Record

public record ProductRecord(String id,String name,Integer qty) 
implements PrintInterface { 
@Override  
public void print() { 
    String productDesc = String.join("-", id, name, qty.toString()); 

System.out.println("商品信息 = " + productDesc); 
 }
}

ProductRecord implements the print() method to print product details.

step3: Test the print method

public static void main(String[] args) {
ProductRecord product = new ProductRecord("P001", "手机", 100); 
product.print();
}

1.2.1.7Local Record

Record can be used as a local object. Define and use Record in the code block, define a SaleRecord below

step1: Define Local Record

public static void main(String[] args) {
//定义Java Record
record SaleRecord(String saleId,String productName,Double money){};
//创建Local Record
SaleRecord saleRecord = new SaleRecord("S22020301", "手机", 3000.0);
//使用SaleRecord
System.out.println("销售记录 = " + saleRecord.toString()); }

Console output: Sales record = SaleRecord[saleId=S22020301, productName=mobile phone, money=3000.0]

1.2.1.8 Nested Records

Multiple Records can be defined in combination, and a Record can contain other Records. We define Record as Customer, which stores customer information, including two Records, Address and PhoneNumber

step1: Define Record

public record Address(String city,String address,String zipcode) {}

public record PhoneNumber(String areaCode,String number) {}

public record Customer(String id, String name, PhoneNumber phoneNumber, Address address) {}

step2: Create a Customer object

public static void main(String[] args) {
Address address = new Address("北京", "大兴区凉水河二街-8号10栋三层", "100176");

PhoneNumber phoneNumber = new PhoneNumber("010", "400-8080-105");

Customer customer = new Customer("C1001", "李项", phoneNumber, address);

System.out.println("客户 = " + customer.toString());
}

Console output: Customer = Customer[id=C1001, name=Li Xiang, phoneNumber=PhoneNumber[areaCode=010, number=400-8080-105], address=Address[city=Beijing, address=9 Liangshuihe Second Street, Daxing District 3rd Floor, Building No. 10, zipcode=100176]]

1.2.1.9 instanceof judges the Record type

instanceof can be used with Java Record. The compiler knows the exact number and type of record components.

step1: Declare Person Record with two attributes name and age

public record Person(String name,Integer age) { }

step2: When a business method judges that it is a Record type, continue to judge whether the age age meets 18 years old.

public class SomeService {
public boolean isEligible(Object obj){
// 判断obj为Person 记录类型
if( obj instanceof Person(String name, Integer age)){
return age >= 18;
}
return false; } }

instanceof can also be used in the following way

if( obj instanceof Person(String name, Integer age) person){
return person.age() >= 18; }

或者

if( obj instanceof Person p){
return p.age() >= 18; }

step3: test code

public static void main(String[] args) { SomeService service = new SomeService();
boolean flag = service.isEligible(new Person("李四", 20));
System.out.println("年龄符合吗?" + flag); }

Console output: The console output flag is true

Record is null in processing judgment

Java Record can automatically handle null.

step1: record is null

public static void main(String[] args) { SomeService service = new SomeService(); 
boolean eligible = service.isEligible(null);
System.out.println("年龄符合吗?" + eligible); }

The console output eligible is false, Debug debugs the code, and finds that the if statement is judged to be false and is not executed.

Summarize

  • The abstract class java.lang.Record is the parent class of all Records.
  • There are definitions for equals(), hashCode(), and toString() methods
  • The Record class can implement java.io.Serializable serialization or deserialization
  • Record supports generics, such as record Gif( T t ) { }
  • The java.lang.Class class has two methods related to the Record class:

boolean isRecord() : Determine whether a class is a Record type RecordComponent[] getRecordComponents(): An array of Record, representing all record components of this record class

Customer customer = new Customer(....);
RecordComponent[] recordComponents = customer.getClass().getRecordComponents(); 
for (RecordComponent recordComponent : recordComponents) {
System.out.println("recordComponent = " + recordComponent);
}
boolean record = customer.getClass().isRecord();
System.out.println("record = " + record);


1.2.2 Switch

Three aspects of Switch, reference: JEP 361

  • Arrow expressions are supported
  • Support yield return value
  • Support Java Record

1.2.2.1 Arrow expressions, new case tags

Switch new syntax, case label -> expression|throw statement|block

case label_1, label_2, ..., label_n -> expression;|throw-statement;|block

step1: new case label

week: Indicates Sunday (1) to Saturday (7), 1 and 7 are rest days, and others are working days. If other than 1-7, no date is required

public static void main(String[] args) {
int week = 7;
String memo = "";
switch (week){
case 1 -> memo = "星期日,休息";
case 2,3,4,5,6-> memo="工作日";
case 7 -> memo="星期六,休息";
default -> throw new IllegalArgumentException("无效的日期:");
}
System.out.println("week = " + memo);
}

1.2.2.2 Yeild return value

Yeild makes switch an expression that can return a value

grammar

variable = switch(value) { case v1: yield result value; case v2: yield result value; case v3,v4,v5.. yield result value }

Example: yield return value, jump out of switch block

​
public static void main(String[] args) { 
int week = 2; 
//yield是switch的返回值, yield跳出当前switch块 
String memo = switch (week){ case 1: yield "星期日,休息"; 
case 2,3,4,5,6: yield "工作日"; 
case 7: yield "星期六,休息"; 
default: yield "无效日期"; };

System.out.println("week = " + memo);

}

​

No intermediate variables are needed, switch is calculated as an expression, and the result can be obtained. yield is the return value of the expression

Example: multiple expressions, case combined with yield

​
public static void main(String[] args) { 
int week = 1; 
//yield是switch的返回值, yield跳出当前switch块 
String memo = switch (week){ 
case 1 ->{ System.out.println("week=1的 表达式部分"); 
yield "星期日,休息"; 
} 
case 2,3,4,5,6 ->{ 
System.out.println("week=2,3,4,5,6的 表达式部分"); 
yield "工作日"; 
} 
case 7 -> { 
System.out.println("week=7的 表达式部分"); 
yield "星期六,休息"; 
} 
default -> { 
System.out.println("其他语句"); 
yield "无效日期"; 
} 
};

System.out.println("week = " + memo);

}

​

hint:

case label -> and case label: cannot be mixed. One syntax format is used in a switch statement block. switch is used as an expression and assigned to a variable, which requires yield or case label -> expression. -> The expression on the right is the return value of the case.

Example:

public static void main(String[] args) { 
int week = 1; 
//yield是switch的返回值, yield跳出当前switch块 
String memo = switch (week){ 
case 1 ->{ 
System.out.println("week=1的 表达式部分"); 
yield "星期日,休息"; 
} 
case 2,3,4,5,6 ->{ 
System.out.println("week=2,3,4,5,6的 表达式部分"); 
yield "工作日"; 
} 
case 7 -> "星期六,休息"; default -> "无效日期";
};

System.out.println("week = " + memo); 
}

1.2.2.3 Java Record

Use record in switch expression, combined with case label -> expression, yield to realize complex calculation

step1: Prepare three Records

public record Line(int x,int y) {

}

public record Rectangle(int width,int height) {

}

public record Shape(int width,int height) {

}

step2: switch record

public static void main(String[] args) { 
Line line = new Line(10,100); 
Rectangle rectangle = new Rectangle(100,200); 
Shape shape = new Shape(200,200);

Object obj = rectangle; 
int result = switch (obj){ 
case Line(int x,int y) -> { 
System.out.println("图形是线, X:"+x+",Y:"+y); 
yield x+y; 
} 
case Rectangle(int w,int h) -> w * h; 
case Shape(int w,int h) ->{ System.out.println("这是图形,要计算周长"); 
yield 2* (w + h); 
} 
default -> throw new IllegalStateException("无效的对象:" + obj); 
}; 
System.out.println("result = " + result);

}

case Line, Rectangle, Shape Execute multiple statements in a code block, or arrow -> expression.

1.2.3 Text Block

Text Block is very convenient to process multi-line text, saving time and effort. There is no need to connect "+", single quotes, newlines, etc. Java 15, refer to JEP 378.

1.2.3.1 Recognizing text blocks

Syntax: Use a string enclosed in three double-quote characters.

""" 
内容 
"""

For example:

String name = """lisi"""; //Error 不能将文本块放在单行上 
String name= """lisi 20"""; 
//Error 文本块的内容不能在没有中间行结束符的情况下跟随三个开头双引号

String myname= """ 
zhangsan 20
"""; 
//正确

Text block definitions require:

  • A block of text begins with three double-quote characters, followed by a line terminator.
  • Can't put text blocks on a single line
  • The contents of a text block also cannot be followed by three opening double quotes without an intermediate line terminator

Three double quotes characters """ are treated the same as two double quotes "". They are used as normal strings. For example, equals(), "==", concatenated strings ("+"), as method parameters, etc.

1.2.3.2 Text blocks are the same as ordinary double-quoted strings

Text Block is used in the same way as ordinary strings, ==, equals comparison, and calling methods of the String class.

step1: string comparison and method

public void fun1() { String s1= """ lisi """; String s2 = """ lisi """;

//比较字符串 boolean b1 = s1.equals(s2); System.out.println("b1 = " + b1);

//使用 == 的比较 boolean b2 = s1 == s2; System.out.println("b2 = " + b2);

String msg = """ hello world"""; //字符串方法substring String sub = msg.substring(0, 5);

 System.out.println("sub = " + sub); }

step2: output the result

b1 = true 
b2 = true 
sub = hello

1.2.3.3 Blank

  • A detailed algorithmic description of whitespace handling is contained in JEP 378.
  • Indentation in Text Block is automatically removed, left and right.
  • To preserve left indentation, spaces. Move the content of the text block to the left (tab key)

Example:

public void fun2(){ 
//按tab向右移动,保留左侧空格 
String html= """ 
动力节点,Java黄埔军校

"""; 
System.out.println( html); 
}

Example 2: indent() method

public void fun3(){ String colors= """ red green blue """;

System.out.println( colors);

//indent(int space)包含缩进,space空格的数量 String indent = colors.indent(5);

 System.out.println( indent);

}

output:

red

green

blue

red      
       green      
       blue

1.2.3.4 Text block methods

Text Block's format method formatted()

public void fun4(){
  String info= """
      Name:%s
      Phone:%s
      Age:%d
      """.formatted("张三","13800000000",20);
  System.out.println("info = " + info);
}

String stripIndent(): Remove the blanks at the beginning and end of each line

String translateEscapes() : convert escape sequences to string literals

1.2.3.5 Escape characters

The new escape character "\" represents a hermit newline character, which is escaped as a space by the Text Block. Common uses are to split very long string literals, concatenate multiple smaller substrings, and wrap multiple lines to generate strings. New escape character for combining very long strings.

example

public void fun5(){
    String str= """
        Spring Boot是一个快速开发框架 \
        基于\"Spring\"框架,创建Spring应用 \
        内嵌Web服务器,以jar或war方式运行 \
        """;
    System.out.println("str = " + str);
}

output

Spring Boot是一个快速开发框架 基于Spring框架,创建Spring应用 内嵌Web服务器,以jar或war方式运行

Summarize:

  • For multi-line strings, Text Block should be used
  • Recommended when Text Block can improve code clarity. For example, embedded SQL statements in the code
  • Avoid unnecessary indentation, opening and closing sections.
  • Use spaces or just tabs to indent text blocks.
  • Mixing whitespace will result in irregular indentation.
  • For most multiline strings, the delimiter is placed at the right end of the previous line, and the closing delimiter is placed on a separate line of the text block.

For example:

String colors= """
        red
        green
        blue
        """;

1.2.4 was

In JDK 10 and above, you can use the var identifier to declare a local variable with a non-null initializer, which can help you write concise code, eliminate redundant information and make the code more readable, use it with caution.

1.2.4.1 var declares local variables

var features

  • var is a reserved word, not a keyword (var can be declared as a variable name)
  • Local variables declared in the method must have an initial value
  • Each time a variable is declared, multiple variables cannot be compounded. var s1="Hello", age=20; //Error
  • The dynamic type of var is that the compiler infers the type based on the value assigned to the variable
  • var replaces the display type, the code is concise, and unnecessary typesetting and confusion are reduced.

Advantages and disadvantages of var

  • The code is concise and tidy.
  • Reduced program readability (no strongly typed declarations)

Example:

//通常
try (Stream<Customer> result = dbconn.executeQuery(query)) {
     //...

//推荐
try (var customers = dbconn.executeQuery(query)) {
    //...
}
    
比较 Stream<Customer> result 与  var customers

1.2.4.2 Use var when using

  • simple temporary variable
  • Complex, multi-step logic, nested expressions, etc., short variables help to understand the code
  • Ability to determine variable initial values
  • When the variable type is relatively long

Example:

public void fun1(){

  var s1="lisi";
  var age = 20;
  for(var i=0;i<10;i++){
    System.out.println("i = " + i);
  }

  List<String> strings = Arrays.asList("a", "b", "c");
  for (var str: strings){
    System.out.println("str = " + str);
  }
  
}

1.2.5 sealed

sealed is translated as sealed. Sealed Classes was first proposed in JEP 360 of Java15, and previewed again in JEP 397 of Java 16, and became a formal function in JEP 409 of Java 17.

The main feature of Sealed Classes is to restrict inheritance

The main feature of Sealed Classes is to limit inheritance. In Java, inheritance is enhanced to extend the capabilities of classes and reuse certain functions. When this ability is out of control. Contrary to the design of the original class, resulting in unforeseen abnormal logic.

Sealed Classes limit unlimited expansion.

There is already a sealed design in Java

  • final keyword, the modified class cannot be inherited
  • private restricts private classes

sealed as a keyword can be used on class and interface, combined with the permits keyword. Define a sealed class that restricts inheritance

1.2.5.1 Sealed Classes

sealed class class name permits subclass 1, subclass N list {}

step1:: declare sealed Class

public sealed class Shape permits Circle, Square, Rectangle {

  private Integer width;
  private Integer height;

  public void draw(){
    System.out.println("=======Shape图形======");
  }
}

permits means allowed subclasses, one or more.

step2:: Declare subclasses

There are three types of subclass declarations

  • final end, still sealed
  • The sealed subclass is a sealed class and needs to be implemented by the subclass
  • non-sealed non-sealed class, extended use, unlimited

Example:

//第一种 final 
public final class Circle extends Shape {

}

//第二种 sealed class 
public sealed class Square extends Shape permits RoundSquare {

@Override public void draw() { System.out.println("=Square图形"); 
} }

//密封类的子类的子类 
public final class RoundSquare extends Square{

}

//非密封类 , 可以被扩展。放弃密封 
public non-sealed class Rectangle extends Shape {

}

//继承非密封类 
public class Line extends Rectangle{

}

Sealed classes do not support anonymous classes and functional interfaces

1.2.5.2 Sealed Interface

The sealing interface is the same as the sealing type

step1: Declare the sealed interface

public sealed interface SomeService permits SomeServiceImpl {

   void doThing();
}

step2: implement the interface

public final class SomeServiceImpl implements SomeService {

  @Override
  public void doThing() {

  }
}


The above classes and interfaces must be in the same package accessible range.

Guess you like

Origin blog.csdn.net/f5465245/article/details/129820382