JAVA 10/11/12/13/14/15/16/17 新特性总结

JAVA 10

局部变量类型推断

在java中,我们可以使用自动类型推断

    public static void main(String[] args) {
        var a = "hello world";
        System.out.println("a = " + a);
    }

但是注意,var 关键字必须位于有初始值设定的变量上,否则编译都不会通过。java终究不像JS那样进行动态推断,这种类型推断仅仅发生在编译期间,到最后编译完成还是会变成具体类型的。

var 关键字不能做为属性或成员变量使用,只能做为局部变量使用。

JAVA 11

Java11 是继 Java8 之后的又一个 TLS 长期维护版本,在Java 17出现之前,一直都是此版本做为广泛使用的版本,其中比较关键的是用于 Lambda 的形参局部变量语法。

用于Lambda的形参局部变量语法

在 Java10 我们认识了 var 关键字,它能够让局部变量自动进行类型推断,不过它不支持在 lambda 中使用,所以在 Java11 终于支持了。

    public static void main(String[] args) {
        Consumer<String> consumer = (var s) -> System.out.println(s.length());
        consumer.accept("你好");
    }

针对String类的方法增强

    public static void main(String[] args) {
        var str = "AB\nC  \nD  ";
        // 判断是否字符串为空或者仅包含空格
        System.out.println(str.isBlank());
        str
                // 根据字符串中的 \n 换行符进行切割,分为多个字符串,并转换为Stream进行操作
                .lines()
                .forEach(System.out::println);

        // 根据传入次数,复制原有字符串并拼接到末尾 "AB\nC\nDAB\nC\nD"
        System.out.println(str.repeat(2));

        // 去除首位空格
        System.out.println(str.strip());
        // 去除首部空格
        System.out.println(str.stripLeading());
        // 去除尾部空格
        System.out.println(str.stripTrailing());
    }

全新的HttpClient使用

在 java9 的时候其实就已经引入了全新的 HttpClient API,用于取代之前比较老的HttpURLConnection类,新的API支持最新的HTTP2和WebSocket协议。

    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
        // 创建一个客户端
        var httpClient = HttpClient.newHttpClient();
        // 创建一个请求
        var request = HttpRequest.newBuilder(new URI("http://www.baidu.com")).GET().build();
        // 发送得到响应
        var send = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(send.body());
    }

java12

java 12-16这五个版本并非长期版本,所以很多特性都是一种处于实验性功能,12/13版本引入了一些实验性功能,并根据反馈进行调整,最后在后续版本中正式开放使用,其实就是体验服的那种感觉。

新的switch语法

新的语法可以大大方便我们的编写,但是还是美中不足的是不能支持范围匹配

    /**
     * 传入分数
     * 90-100 优秀
     * 70-90 良好
     * 60-70 及格
     * 0-60 差
    **/
    public static String old(int score){
        score/=10;
        String str;
        switch (score){
            case 10:
            case 9:
                str = "优秀";
                break;
            case 8:
            case 7:
                str = "良好";
                break;
            case 6:
                str = "几个";
                break;
            default:
                str = "不及格";
        }
        return str;
    }

    public static String java12(int score){
        score/=10;
        return switch (score){
            case 10,9 -> "优秀";
            case 8,7 -> "良好";
            case 6 -> "几个";
            default -> "不及格";
        };
    }

    public static String java12_1(int score){
        score/=10;
        return switch (score){
            case 10,9 -> "优秀";
            case 8,7 -> "良好";
            case 6 -> "几个";
            default -> {
                System.out.println("其他方式");
                yield "不及格";
            }
        };
    }

java13

文本块

当我们需要使用复杂字符串时,可能字符串中包含了很多需要转移的字符,比如双引号等,这时我们就可以使用三引号来囊括字符串

    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
        var s = """
                    dsafdsafdsa
                        dfdsafd
                            ""fdsa \n \n dsfdsa
                            \r ffff \t dsfad 
                """;
        System.out.println(s);
    }

结果打印:
    dsafdsafdsa
        dfdsafd
            ""fdsa 
 
 dsfdsa
 ffff    dsfad

java14

新的 instanceof 语法

    public boolean old(Object o) {
        if (this == o) {return true;}
        if (o instanceof User) {
            User user = (User) o;
            return user.name.equals(this.name);
        }
        return false;
    }

    public boolean java16(Object o) {
        if (this == o) {return true;}
        if (o instanceof User user) {
            return user.name.equals(this.name);
        }
        return false;
    }

空指针异常的改进

在旧版本中如果出现空指针异常,报错只会给我们空指针发生在哪一行,具体哪个变量为空并不会告诉我们,需要我们自己打debug,在新的版本中会明确告知我们。

记录类型 Record

继类、接口、枚举、注解之后的又一新类型来了,他的名字叫记录,在java14中首次出场,这一出场,Lombok 的噩梦来了。 在实际开发中,很多类仅仅只是充当一个实体类罢了,保存的是一些不可变数据,比如我们从数据库中查询的账户信息,最后被映射为一个实体类

@Data
public class User {

    private String name;
  
    private Integer age;
}

Lombok 可以说时简化代码的神器,它能在编译时自动生成 get、set、构造器、toString()方法等,在编写这些实体类时,简直不要太好用,Record可以让我们不需要显式地定义构造函数、getters方法或equals和hashCode方法。所有这些都会由Records自动生成。

记录类型本质上也是一个普通类,不过是 final 类型且继承自 java.lang.Record抽象类的,他会在编译时,会自动编译出 get、hashCode、equals、toString等方法。

// 只能把字段写道括号中
public record User(String name,Integer age) {
    public static void a(){
    }
    public static void main(String[] args) {
        User user = new User("张三",2);
        System.out.println(user.name());
        System.out.println(user);
    }

}

但有些功能还是没有办法与 Lombok 相比的,如 @SL4J,链式调用,无参构造函数不支持等。

java17

密封类型

密封类型可以说时java17正式推出的又一重磅类型,它在java15首次提出并测试了两个版本。

在java中,我们可以通过继承(extends关键字)来实现类的能力复用,扩展与增强。但有的时候,可能并不是所有的类我们都希望能够被继承。所以,我们需要对继承关系有一些限制的控制手段,而密封类的作用就是限制类的继承。实际上在之前我们如果不希望别人继承我们的类,可以直接添加 final 关键字。

这样有一个缺点,如果添加了 final 关键字,那么无论是谁,包括我们自己也是没办法实现继承的,但是现在我们有一个需求,只允许我们自己写的类继承,但是不允许别人写的类继承,这时该咋写?在java17之前想要实现就很麻烦。

# 旧版本
public final class A{
}

# 新版本 sealed
public sealed class A permits B {
}
# 继承 A
public final class B extends A {
}
public sealed class B extends A {
}
public non-sealed B extends A {
}

密封类型有以下要求:

  • 可以基于普通类、抽象类、接口,也可以继承自其他接口的子类或是实现其他接口的类等。
  • 必须有子类继承,且不能是匿名内部类或是lambda的形式
  • sealed 写在原来 final 的位置,但不能和 final、non-sealed 关键字同时出现,只能选其一
  • 继承的子类必须显示的标记为final(表示这个类不能被继承)、sealed(表示这个子类也可以有其他密封的或非密封的子类) 或是 non-sealed (表示这个子类不能有子类,但它可以被其他类继承)类型
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容