JDK8之后的新特性
一些常用的新特性
instanceof
旧的写法:
Object x = "abcdef";
if (x instanceof String) {
String a = (String) x;
x = a.trim();
}
新的写法:
Object x = "abcdef";
if (x instanceof String a) {
x = a.trim();
}
try-with-resource
之前在使用IO流之类的都需要手动关闭:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = bufferedReader.readLine();
OutputStreamWriter out = new OutputStreamWriter(System.out);
BufferedWriter bufferedWriter = new BufferedWriter(out);
bufferedWriter.write("你输入的内容为:" + line);
bufferedWriter.flush();
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
现在通过观察类的关系图可以发现,这些类都直接或者间接的实现了AutoCloseable
、Closeable
接口,所以现在可以将需要关闭的资源写到try(需要关闭的资源)
中,此时不能够再次修改这些变量的值了,可以把这些值当成常量。
import java.io.*;
public class Main {
public static void main(String[] args) {
try (
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
OutputStreamWriter out = new OutputStreamWriter(System.out);
BufferedWriter bufferedWriter = new BufferedWriter(out);
) {
String line = bufferedReader.readLine();
bufferedWriter.write("你输入的内容为:" + line);
bufferedWriter.flush();
} catch (IOException e) {
}
}
}
还有其他写法,如果所有的对象都在try()
中会显得比较奇怪,可以按照以下写法:
import java.io.*;
public class Main {
public static void main(String[] args) {
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
OutputStreamWriter out = new OutputStreamWriter(System.out);
BufferedWriter bufferedWriter = new BufferedWriter(out);
try (inputStreamReader; bufferedReader; out; bufferedWriter) {
String line = bufferedReader.readLine();
bufferedWriter.write("你输入的内容为:" + line);
bufferedWriter.flush();
} catch (IOException e) {
}
}
}
switch
旧的写法:
public class Main {
public static void main(String[] args) {
int x = 5;
switch (x) {
case 1:
System.out.println("一");
break;
case 2:
System.out.println("二");
break;
case 3:
System.out.println("三");
break;
default:
System.out.println("大于三");
}
}
}
可以看到需要退出的地方都需要手动添加break
,可以使用以下方式:
public class Main {
public static void main(String[] args) {
int x = 5;
switch (x) {
case 1 -> System.out.println("一");
case 2 -> System.out.println("二");
case 3 -> System.out.println("三");
default -> System.out.println("大于三");
}
}
}
多条语句需要添加花括号:
public class Main {
public static void main(String[] args) {
int x = 5;
int result = 0;
switch (x) {
case 1:
System.out.println("一");
result = x * 10;
break;
case 2:
System.out.println("二");
result = x * 10;
break;
case 3:
System.out.println("三");
result = x * 10;
break;
default:
System.out.println("大于三");
result = x * 10;
}
System.out.println("乘以10之后的结果为:" + result);
}
}
public class Main {
public static void main(String[] args) {
int x = 5;
int result = 0;
switch (x) {
case 1 -> {
System.out.println("一");
result = x * 10;
}
case 2 -> {
System.out.println("二");
result = x * 10;
}
case 3 -> {
System.out.println("三");
result = x * 10;
}
default -> {
System.out.println("大于三");
result = x * 10;
}
}
System.out.println("乘以10之后的结果为:" + result);
}
}
多个相同的结果可以写在一块:
public class Main {
public static void main(String[] args) {
int x = -2;
int result = 0;
switch (x) {
case -1, -2, -3 -> System.out.println("-1、-2、-3");
case 1 -> {
System.out.println("一");
result = x * 10;
}
case 2 -> {
System.out.println("二");
result = x * 10;
}
case 3 -> {
System.out.println("三");
result = x * 10;
}
default -> {
System.out.println("大于三");
result = x * 10;
}
}
System.out.println("乘以10之后的结果为:" + result);
}
}
接受值
也可以接收返回值
旧的写法:
public class Main {
public static void main(String[] args) {
int x = 5;
int result = 0;
switch (x) {
case 1:
result = 1 * 10;
break;
case 2:
result = 2 * 10;
break;
case 3:
result = 3 * 10;
break;
default:
result = x * 10;
}
System.out.println(result);
}
}
新的写法:
public class Main {
public static void main(String[] args) {
int x = 5;
int result = switch (x) {
case 1 -> 1 * 10;
case 2 -> 2 * 10;
case 3 -> 3 * 10;
default -> x * 10;
};
System.out.println(result);
}
}
yield
如果有多个语句可以使用yield
关键字将值返回
public class Main {
public static void main(String[] args) {
int x = 2;
int result = switch (x) {
case -1, -2, -3 -> {
System.out.println("-1、-2、-3");
yield x + 1;
}
case 1 -> {
System.out.println("一");
yield x * 10;
}
case 2 -> {
System.out.println("二");
yield x * 10;
}
case 3 -> {
System.out.println("三");
yield x * 10;
}
default -> {
System.out.println("大于三");
yield x * 10;
}
};
System.out.println("乘以10之后的结果为:" + result);
}
}
和函数结合在一块:
public class Main {
public static void main(String[] args) {
int x = 2;
int result = conversionResult(x);
System.out.println("乘以10之后的结果为:" + result);
}
private static int conversionResult(int x) {
return switch (x) {
case -1, -2, -3 -> {
System.out.println("-1、-2、-3");
yield x + 1;
}
case 1 -> {
System.out.println("一");
yield x * 10;
}
case 2 -> {
System.out.println("二");
yield x * 10;
}
case 3 -> {
System.out.println("三");
yield x * 10;
}
default -> {
System.out.println("大于三");
yield x * 10;
}
};
}
}
文本块
可以用""" """
来标识一段多行文本
\s
:表示空格\
:表示不换行\s\
表示添加一个空格且不换行
之前的写法:
public class Main {
public static void main(String[] args) {
String sql = "select *\n" +
"from pms_category\n" +
"order by cat_id desc;";
System.out.println("sql = " + sql);
}
}
现在的写法:
public class Main {
public static void main(String[] args) {
String sql = """
select *
from pms_category
order by cat_id desc;
""";
System.out.println("sql = " + sql);
sql = """
select *\s\
from pms_category\s\
order by cat_id desc;
""";
System.out.println("sql = " + sql);
}
}
record
仅作为数据类进行使用
特性:
- 所有的属性相当于使用了
final
进行修饰了 - 不允许定义为
abstract
- 能够自动生成
hashcode
、equals
、toString
、全部参数的构造器 - 不能够显式的继承其他类,也不能够被其他类继承
- 这个类相当于继承自
java.lang.Record
- 相当于这个类被添加了
final
关键字
- 这个类相当于继承自
record
体中可以写静态方法、静态属性,但不允许写实例属性、实例方法- 可以写构造方法,但必须调用
this(所有的参数)
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("贝贝", "这是一条狗", 10, true);
System.out.println("dog = " + dog);
Dog dog2 = new Dog("贝贝", "这是一条狗", 10, true);
System.out.println("dog.equals(dog2) = " + dog.equals(dog2));
System.out.println("----------------------");
System.out.println("dog.age() = " + dog.age());
System.out.println("dog.name() = " + dog.name());
System.out.println("dog.description() = " + dog.description());
System.out.println("dog.age() = " + dog.age());
System.out.println("dog.sex() = " + dog.sex());
System.out.println("----------------------");
System.out.println("Dog.content = " + Dog.content);
System.out.println("Dog.getInstance() = " + Dog.getInstance());
System.out.println("----------------------");
System.out.println("new Dog(\"aaaa\") = " + new Dog("aaaa"));
}
}
record Dog(String name, String description, int age, boolean sex) {
static String content = "这是内容";
static Dog getInstance() {
return new Dog(null, null, 0, false);
}
Dog(String name) {
this(name, null, 0, false);
}
}
密封类 sealed
可以标识一个类能够被哪几个类继承
sealed
读音为/siːld/
,中文为密封
permits
读音为/pərˈmɪts/
,中文为允许
sealed class 类名 permits 允许被继承的类1, ..., 类n {
}
子类需要使用:
no-sealed
:表示这个子类还可以被其他子类继续继承sealed
:表示这个子类也是密封的final
:表示这个类不能够继续被继承了
sealed class Animal permits Dog, Cat, Fish {
}
final class Dog extends Animal {
}
sealed class Cat extends Animal permits BigCat, SmallCat {
}
final class BigCat extends Cat {
}
final class SmallCat extends Cat {
}
non-sealed class Fish extends Animal {
}
class BigFish extends Fish {
}
Q.E.D.