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

现在通过观察类的关系图可以发现,这些类都直接或者间接的实现了AutoCloseableCloseable接口,所以现在可以将需要关闭的资源写到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
  • 能够自动生成hashcodeequalstoString、全部参数的构造器
  • 不能够显式的继承其他类,也不能够被其他类继承
    • 这个类相当于继承自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.


念念不忘,必有回响。