前言:Java在2021年发布了最新的长期支持版本:JDK 17。这个版本引入了许多新的语法特性,提升了开发效率和代码可读性。本文将简要介绍一些常见的新特性,帮助开发者快速掌握并应用于实际开发中。
✨✨✨这里是秋刀鱼不做梦的BLOG
✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客
先让我们看一下本文大致的讲解内容:
1.yield关键词
——先让我们来了解一下yield关键词的作用:
yield
关键字,用于增强switch
表达式,使其能够返回值。yield
允许switch
表达式在不同的分支中返回特定的值,并将其赋给变量。
先让我们来看一个正常的switch的例子:
public class Test { public static void main(String[] args) { String data = "one"; int result = 0; // 接收数据的返回值 switch (data) { case "one": result = 1; // 为result重新赋值 break; case "two": result = 2; // 为result重新赋值 break; default: result = -1; // 为result重新赋值 break; } System.out.println(result); } }
代码分析:
定义类和主方法:代码定义了一个名为
Test
的类,并包含一个main
方法,这是程序的入口点。初始化变量:声明并初始化了两个变量,
data
和result
。data
被赋值为字符串"one",result
被初始化为0。switch语句:
根据
data
的值进行判断。如果
data
的值是"one",则执行result = 1;
,并通过break
跳出switch
语句。如果
data
的值是"two",则执行result = 2;
,并通过break
跳出switch
语句。如果
data
的值不是"one"或"two",则执行default
块,将result
赋值为-1,并通过break
跳出switch
语句。输出结果:通过
System.out.println(result);
将result
的值输出到控制台。
现在让我们将上述的代码进行简化,简化后的switch:
public static void main(String[] args) { String data = "one"; int result = switch (data) { case "one" -> 1; case "two" -> 2; default -> -1; }; System.out.println(result); }
我们发现我们可以使用->来返回switch语句的值,当然有读者会问了,这和我们讲解的yield有什么关系呢?,接下来让我们将上述代码转换为yield的形式:
public static void main(String[] args) { String data = "one" ; int result = switch (data) { case "one" : yield 1; case "two": yield 2; default : yield -1; }; System.out.println(result) ; }
我们可以发现我们也可以使用yield来返回switch的值,这就是yield语句。
2.var关键词
var
是Java 10中引入的一个新特性,用于局部变量类型推断。它允许编译器在编译时自动推断变量的类型,从而简化代码书写和增强代码可读性。
接下来我们直接使用实例来进行讲解:
以下是一个使用var
的示例:
import java.util.ArrayList; public class VarExample { public static void main(String[] args) { // 使用var声明整型变量 var number = 10; System.out.println("Number: " + number); // 使用var声明字符串变量 var text = "Hello, Java 10!"; System.out.println("Text: " + text); // 使用var声明集合 var list = new ArrayList<String>(); list.add("Apple"); list.add("Banana"); System.out.println("List: " + list); // 使用var声明迭代器 for (var item : list) { System.out.println("Item: " + item); } } }
从上述的代码我们可以看到,我们使用var关键词来声明变量,其会自动的推断类型。这大大的方便了我们声明变量。
注意:
虽然var关键词可以推断出变量的类型,但是不要什么时候都使用var关键词来声明变量,一般在类型名称非常长的时候,例如泛型,我们会使用var来简化代码。
例如:
public static void main(String[] args) { Map<String, List<Map<Integer, String>>> complexMap = new HashMap<String, List<Map<Integer, String>>>(); //使用var关键词进行简化 var complexMap2 = new HashMap<String, List<Map<Integer, String>>>(); }
我们可以发现这样我们的代码繁琐度大大的简化了。
注意事项:
var
只能用于局部变量声明,不能用于成员变量、方法参数或返回类型。变量必须在声明时初始化,因为编译器需要根据初始化值来推断变量类型。
var
不能用于没有初始化值的变量声明。var
不能用于null
初始化,因为无法推断类型。
以上就是Java中的var关键词的使用了。
3.密封类 - sealed
在讲解sealed关键词之前,先让我们讲解一下什么是密封类:
密封类(Sealed Classes)是一项语言特性,旨在更好地控制类层次结构中的继承关系。通过使用密封类,开发者可以明确指定哪些类可以继承某个类,从而增强类型安全性和代码可维护性。
我们知道,在Java中使用final修饰的类为密封类,其作用就是不能被其他类所继承,如果被继承就会报错,例如:
// 定义一个final类 public final class FinalClass { private String message; public FinalClass(String message) { this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } // 尝试继承final类 public class SubClass extends FinalClass { // 这行会导致编译错误 public SubClass(String message) { super(message); } }
当然,在JDK17中提供了一个新的关键字: sealed 。它允许你显式地列出可以扩展某个类或实现某个接口的类,从而增强了类型安全性和可维护性。
—— 那么怎么使用sealed关键词呢?
使用sealed
关键字的步骤如下:
(1)声明一个
sealed
类或接口。(2)使用
permits
关键字明确允许哪些类可以继承该sealed
类或接口。(3)被允许的子类必须是
final
,sealed
,或non-sealed
的。
让我们直接使用案例来帮助你进行理解:(代码如下)
// 定义一个sealed类 public sealed class Shape permits Circle, Rectangle, Square { // 声明一个抽象方法area,要求任何继承Shape的子类必须实现这个方法 public abstract double area(); } // 定义一个final子类 public final class Circle extends Shape { // 声明一个私有的最终变量radius,用于存储圆的半径 private final double radius; // Circle类的构造方法,接收一个半径参数并初始化radius public Circle(double radius) { this.radius = radius; } // 实现Shape类中声明的抽象方法area,计算并返回圆的面积 @Override public double area() { return Math.PI * radius * radius; } } // 定义一个sealed子类 public sealed class Rectangle extends Shape permits FilledRectangle { // 声明两个私有的最终变量width和height,用于存储矩形的宽和高 private final double width; private final double height; // Rectangle类的构造方法,接收矩形的宽和高参数并初始化width和height public Rectangle(double width, double height) { this.width = width; this.height = height; } // 实现Shape类中声明的抽象方法area,计算并返回矩形的面积 @Override public double area() { return width * height; } } // 定义一个non-sealed子类 public non-sealed class Square extends Shape { // 声明一个私有的最终变量side,用于存储正方形的边长 private final double side; // Square类的构造方法,接收一个边长参数并初始化side public Square(double side) { this.side = side; } // 实现Shape类中声明的抽象方法area,计算并返回正方形的面积 @Override public double area() { return side * side; } } // 进一步定义一个final子类 public final class FilledRectangle extends Rectangle { // 声明一个私有的最终变量color,用于存储填充矩形的颜色 private final String color; // FilledRectangle类的构造方法,接收矩形的宽、高和颜色参数,并调用父类Rectangle的构造方法进行初始化 public FilledRectangle(double width, double height, String color) { super(width, height); this.color = color; } // 添加一个额外的方法getColor,用于获取填充矩形的颜色 public String getColor() { return color; } }
在这个例子中:
1. Shape
是一个sealed
类,只有Circle
,Rectangle
和Square
可以继承它。
2. Circle
是一个final
类,不能被进一步继承。
3. Rectangle
是一个sealed
类,只有FilledRectangle
可以继承它。
4. Square
是一个non-sealed
类,可以被进一步继承
并且我们要注意:
1. sealed修饰的类必须要有子类;
2. 未被permits 允许的类型,则没办法继承;
3. 子类使用final修饰则不可以继承发生继承;
4. 子类使用 non-sealed 关键字修饰。表示不限制,任何类都可以继承;
5. 子类使用sealed关键词的可以继承发生继承;
这样我们就大致的了解了sealed关键词了。
4.接口中的私有方法
在接口中的私有方法常常用于对接口中的default修饰的方法和静态方法进行辅助,将其内部的代码进行封装简化。
例如:
interface HelloService { public void sayHello(); // 默认方法 default void saySomething(){ syaEngHello(); sayHello(); }; // 私有方法 private void syaEngHello(){ System.out.println("Hello!"); }
接口的私有方法为Java语言引入了更多的灵活性和功能性,可以帮助编写更干净、更模块化的代码,提升了接口的设计和实现的效率和质量。
这就是Java中接口中的私有方法的使用。
5.instanceof关键词
在Java中,instanceof
是一个关键字,用于测试一个对象是否是一个类的实例或者是其子类的实例。它的语法形式如下:
object instanceof type
其中,object
是要检查的对象,type
是一个类名或接口名。instanceof
操作符的作用是检查object
是否是type
类型的实例,或者是type
类型的子类的实例。它返回一个布尔值,如果object
是type
类型或其子类的实例,则返回true
;否则返回false
。
——接下来让我们使用一个实例来进行对其进一步理解:
class Animal { // Animal 类的成员和方法 } class Dog extends Animal { // Dog 类的成员和方法 } public class Main { public static void main(String[] args) { Animal animal = new Dog(); // 创建一个 Dog 对象并赋值给 Animal 类型的变量 // 使用 instanceof 来检查对象的类型 if (animal instanceof Dog) { System.out.println("animal 是 Dog 类的实例"); } if (animal instanceof Animal) { System.out.println("animal 是 Animal 类的实例"); } if (animal instanceof Object) { System.out.println("animal 是 Object 类的实例"); } } }
解释:
Animal
是一个类,Dog
是Animal
的子类。在
main
方法中,创建了一个Dog
对象,并将其赋值给一个Animal
类型的变量animal
。使用
instanceof
关键字,首先检查animal
是否是Dog
类的实例,结果为true
,因为animal
确实是Dog
类的实例。接着检查
animal
是否是Animal
类的实例,同样为true
,因为Dog
类是Animal
类的子类。最后检查
animal
是否是Object
类的实例,结果同样为true
,因为所有类在Java中最终都是继承自Object
类的。
通过上面的讲解,我相信你已经对Java中instanceof关键词有了一定的理解,那么instanceof关键词有什么用处呢?
instanceof的用途:
类型检查和转换:
instanceof
通常用于在运行时检查对象的类型,以便进行类型转换或根据对象的实际类型执行特定的操作。条件控制:可以根据对象的类型来决定执行不同的代码路径,以实现多态性和灵活的程序逻辑。
安全性检查:在某些情况下,使用
instanceof
可以帮助避免类型转换异常(ClassCastException
),在进行类型转换之前先检查对象的类型是否符合预期。
这样我们就大致的了解了Java中的instanceof关键词了。
以上就是本篇文章的全部内容了~~~