SpringBoot教程-俗易懂高薪必备【SpringBoot3从入门到项目实战】

配套视频:www.bilibili.com/video/BV1Km…icon-default.png?t=N2N8https://link.juejin.cn?target=https%3A%2F%2Fwww.bilibili.com%2Fvideo%2FBV1Km4y1k7bn%2F%3Fvd_source%3D24b6cf5b24b14d71dd56d52a13db458c

1.   JDK 关注的新特性

1.1    搭建学习环境

JDK:JDK19

OpenJDK: https://jdk.java.net/19/

Liberica JDK: Download Java | Java 8, Java 11, Java 17, Java 20 - OpenJDK Builds for Linux, Windows & macOS    ,  是一个 OpenJDK 发行版,为云原生,容器特别优化。

Maven:构建和依赖管理,版本选择 3.6 以上

配置本地仓库和阿里云镜像

IDEA2022.3. 1Ultimate :主要的开发工具,我是 30 天试用版本

数据库:MySQL 5 以上版本

火狐浏览器:版本用比较新的,中文版本。

文本工具:EditPlus, Sublime 任意。

1.2    有用的新特性

JDK8- 19 新增了不少新特性,这里我们把实际常用的新特性,给大家介绍一下。包括以下几个方面:

     Java Record

     Swich 开关表达式

     Text Block 文本块

     var  声明局部变量

     sealed  密封类

1.2.1    Java Record

Java14 中预览的新特性叫做 Record ,在 Java 中,Record 是一种特殊类型的 Java 类。可用来创建不可变类,语法 简短。参考[JEP 395](https://openjdk.java.net/jeps/395).    Jackson 2. 12 支持 Record 类。

任何时候创建 Java类,都会创建大量的样板代码,我们可能做如下:

  •   每个字段的 set ,get 方法
  •   公共的构造方法
  •   重写 hashCode, toString(), equals()方法

Java Record 避免上述的样板代码,如下特点:

  •   带有全部参数的构造方法
  •      public 访问器
  •      toString(),hashCode(),equals()
  •   无 set ,get 方法。没有遵循 Bean 的命名规范
  •      final 类,不能继承 Record ,Record 为隐士的 final 类。除此之外与普通类一样
  •   不可变类,通过构造创建 Record
  •      final 属性,不可修改
  •   不能声明实例属性,能声明 static 成员

IDEA 创建新的 Maven 工程 Lession01-feature

1.2.1.1    看看 Record 怎么用

IDEA 新建 Class ,选择类 Record

step1:  创建 Student Record

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

step2:创建 Record 对象

 
public static void main(String[] args) {

Student lisi = new Student(1001, "lisi","lisi@qq.com",20) ; System.out.println("lisi = " + lisi.toString()) ;

Student zhangsan = new Student(1002, "zhangsan","lisi@qq.com",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()) ;

}

现在能查看控制台输出:

public static void main(String[] args) {

Student lisi = new Student(1001, "lisi","lisi@qq.com",20) ; System.out.println("lisi = " + lisi.toString()) ;

Student zhangsan = new Student(1002, "zhangsan","lisi@qq.com",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()) ;

}

Record 通过构造方法创建了只读的对象,能够读取每个属性,不能设置新的属性值。  Record 用于创建不可变的 对象,同时减少了样板代码。

Record 对每个属性提供了 public 访问器,例如 lisi.name()

1.2.1.2    Instance Methods

Record 是 Java 类,和普通 Java 类一样定义方法。下面定义方法 concat ,将姓名和年龄一起打印输出。 我们创建普通的方法 concat ,将 name 和 age 连接为一个字符串输出。

step1:创建实例方法

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

step2:  调用实例方法

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

最后控制台输出:

姓名:lisi ,年龄是:20

1.2.1.3    静态方法 Static Method

Record 类定义静态方法,试用静态方法与普通类一样。

step1:  创建静态方法

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:测试静态方法

public static void main(String[] args) {

String emailUpperCase = Student.emailUpperCase("lisi@163.com") ;

System.out.println("emailUpperCase = " + emailUpperCase) ;

}

1.2.1.4    Record 的构造方法

我们可以在 Record 中添加构造方法,  有三种类型的构造方法分别:是紧凑的,规范的和定制构造方法   紧凑型构造方法没有任何参数,甚至没有括号。

  规范构造方法是以所有成员作为参数

  定制构造方法是自定义参数个数

step1:  紧凑和定制构造方法

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:编译 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 与 Lombok

Java Record 是创建不可变类且减少样板代码的好方法。Lombok 是一种减少样板代码的工具。两者有表面上的重叠部 分。可能有人会说Java Record 会代替 Lombok.  两者是有不同用途的工具。

Lombok 提供语法的便利性,通常预装一些代码模板,根据您加入到类中的注解自动执行代码模板。这样的库纯粹是 为了方便实现 POJO 类。通过预编译代码。将代码的模板加入到class 中。

Java Record 是语言级别的,一种语义特性,为了建模而用,数据聚合。简单说就是提供了通用的数据类,充当“数据 载体" ,用于在类和应用程序之间进行数据传输。

1.2.1.6    Record 实现接口

Java Record 可以与普通类一样实现接口,重写接口的方法。

step1:  创建新的接口,定义一个规范方法。

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

step2:  创建新的 Record 实现接口,重写接口的方法,实现当前 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 实现 print()方法,打印商品详情。

step3:测试 print 方法

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

1.2.1.7    Local Record

Record 可以作为局部对象使用。在代码块中定义并使用 Record ,下面定义一个 SaleRecord

step1:定义 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) ; //使用 SaleRecor

System.out.println("销售记录 = " + saleRecord.toString()) ;


}

控制台输出:

销售记录 = SaleRecord[saleId=S22020301, productName=手机, money=3000.0]

1.2.1.8    嵌套 Record

多个 Record 可以组合定义,  一个 Record 能够包含其他的 Record。

我们定义 Record 为 Customer ,存储客户信息,包含了 Address 和 PhoneNumber 两个 Record

step1:定义 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) {}

tep2:  创建 Customer 对象

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()) ;

}

控制台输出:

客户 = Customer[id=C1001, name=李项, phoneNumber=PhoneNumber[areaCode=010, number=400-8080- 105], address=Address[city=北京, address=大兴区凉水河二街 9 号 10 栋三层, zipcode= 100176]]

1.2.1.9    instanceof 判断 Record 类型

instanceof 能够与 Java Record 一起使用。编译器知道记录组件的确切数量和类型。

step1:声明 Person Record ,拥有两个属性 name 和 age

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

step2:  在一个业务方法判断当是 Record 类型时,继续判断 age 年龄是否满足 18 岁。

public class SomeService {

public boolean isEligible(Object obj) {

// 判断 obj 为 Person 记录类型

if( obj instanceof Person(String name, Integer age)) {

return age >= 18 ;

}

return false ;

}

}

instanceof 还可以下面的方式

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

step3:  测试代码

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

控制台输出:

控制台输出 flag 为true

处理判断中 Record 为 null

Java Record 能够自动处理 null。

step1 :record 为 null

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

}

控制台输出 eligible 为 false  ,Debug 调试代码,发现 if 语句判断为 false ,不执行

总结

  •      abstract 类 java.lang.Record 是所有 Record 的父类。
  •    有对于 equals() ,hashCode() ,toString()方法的定义说明
  •       Record 类能够实现 java.io.Serializable 序列化或反序列化
  •       Record 支持泛型,例如 record Gif<T>( T t ) { }
  •      java.lang.Class 类与 Record 类有关的两个方法:

1

2

boolean isRecord() : 判断一个类是否是 Record 类型

RecordComponent[] getRecordComponents():Record 的数组,表示此记录类的所有记录组件

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

Switch 的三个方面,参考:JEP 361

  支持箭头表达式

  支持 yied 返回值

  支持 Java Record

1.2.2.1    箭头表达式,新的 case 标签

Switch 新的语法,case label ->  表达式|throw  语句|block

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

step1:新的 case  标签

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) ;
}

week:表示周日 (1) 到周六 (7) ,1 和 7 是休息日,其他是工作日。如果 1-7 以外为无需日期

1.2.2.2    yeild 返回值

yeild 让 switch 作为表达式,能够返回值

语法

变量 = switch(value) { case v1:    yield  结果值; case v2: yield  结果值;case v3,v4,v5.. yield  结果值 }

无需中间变量,  switch作为表达式计算,可以得到结果。yield 是表达式的返回值

示例:多表达式,  case  与 yield  结合使用

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) ;

无需中间变量,  switch作为表达式计算,可以得到结果。yield 是表达式的返回值

示例:多表达式,  case  与 yield  结合使用

 未完待续……

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值