浅谈java14超实用新特性(纯干货)

直接上干货。

jdk14的安装和新版idea的安装就不说了,下面奉上两个软件。

链接:https://pan.baidu.com/s/1eBd6fmlkK5qF5ulJM9HJfw 提取码:vst7

安装完成之后如下:2020年3月17发布的

idea还有几个小设置:

ok,设置完毕,直接进入正题。

总共:5个语法改变,3个虚拟机优化,详细介绍往下看。

语法层面优化总共五处。以下的预览代表还未正式确认,让使用者提意见的。

语法一:instanceof的模式匹配(预览) ​​​

什么意思?一脸懵逼??直接上代码:

public class Feature01 {
    @Test
    public void test1(){

        Object obj = new String("hello,Java14");

        //jdk14之前的写法
        if(obj instanceof String){
            String str = (String) obj;
            System.out.println(str.contains("Java"));
        }else{
            System.out.println("非String类型");
        }

        //举例1:
        //新特性:省去了强制类型转换的过程,但是此时的str作用域只限于if内
        if(obj instanceof String str){
            System.out.println(str.contains("Java"));
        }else{
            System.out.println("非String类型");
        }
    }
}

实际上就是之前的两行代码,判断+强转 变成了一句代码。

//之前
if(obj instanceof String){
    String str = (String) obj;
    System.out.println(str.contains("Java"));
}
//jdk14
if(obj instanceof String str){
    System.out.println(str.contains("Java"));
}

注意:jdk14里面 此时的str的作用域仅限于if结构内

再看下一个例子:

//举例2:
class Monitor{
    private String model;
    private double price;

    //复杂写法
    public boolean equals(Object o){
        if(o instanceof Monitor other){
            if(model.equals(other.model) && price == other.price){
                return true;
            }
        }
        return false;
    }
    //简单写法
    public boolean equalsSimple(Object o){
        return o instanceof Monitor other && model.equals(other.model) && price == other.price;
    }

}

语法二:非常实用的NullPointerException

大白话来说就是 提示空指针异常的地方变得更具体,更准确了。代码如下:

简介一下如下代码:

Bank类有个私有属性Customer类,Customer类中有个私有属性Account类,Account中有个withdraw(double amt)的方法。

public class Feature02 {
    public static void main(String[] args) {
        //这样是不会报错的
//        Bank bank = new Bank(new Customer(new Account(1000)));

        //但是这样就会报错了,因为Customer类的私有属性 Account没有被new出来,直接调用withdraw方法,空指针
        Bank bank = new Bank(new Customer());
        //但是这样就会报错了,因为Customer类的私有属性 Account没有被new出来,直接调用withdraw方法,空指针
        bank.getCustomer().getAccount().withdraw(200);
    }

}

class Bank {
    private Customer customer;

    public Bank() {
    }

    public Bank(Customer customer) {
        this.customer = customer;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}

class Customer {
    private Account account;

    public Customer() {
    }

    public Customer(Account account) {
        this.account = account;
    }

    public Account getAccount() {
        return account;
    }

    public void setAccount(Account account) {
        this.account = account;
    }
}

class Account {
    private double balance;//余额

    public Account() {
    }

    public Account(double balance) {
        this.balance = balance;
    }

    //取钱操作
    public void withdraw(double amt) {
        if (balance >= amt) {
            balance -= amt;
            System.out.println("成功取款:" + amt);
        } else {
            System.out.println("余额不足,取款失败");
        }
    }
}

以前的报错大家很熟悉,普通空指针。如下

但是jdk14,有个虚拟机参数如下:

-XX:+ShowCodeDetailsInExceptionMessages

我们设置一下这个参数,再来看看结果

运行结果:

直接贴出来吧:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.herman.feature.Account.withdraw(double)" because the return value of "com.herman.feature.Customer.getAccount()" is null

可以清楚的看出是 "com.herman.feature.Customer.getAccount()" is null报错,这就很nice。。

语法三:Record(预览特性)

神说要用record,于是就有了 。什么意思??直接上代码吧。感觉这个 局限性有点高,可能开发用的不多。

之前我们用的lombok插件,就是为了解决实体/bean中的get set方法,构造器,toString,equals等服务的,这次新增了Record。

我们以前写实体,一般写法如下:属性然后 get set toString equals 写一堆。

多注意这里的final修饰。record反编译之后,属性都被final修饰了。

看着很是麻烦重复,jdk14引入新写法如下:

public record Person(String name,Person partner) {
}

??完了?就这么简单? 没错 就这么简单。

测试代码如下:

public class Feature03 {
    @Test
    public void test1(){
        //测试构造器
        Person p1 = new Person("罗密欧",new Person("zhuliye",null));
        //测试toString()
        System.out.println(p1);
        //测试equals():
        Person p2 = new Person("罗密欧",new Person("zhuliye",null));
        System.out.println(p1.equals(p2));

        //测试hashCode()和equals()
        HashSet<Person> set = new HashSet<>();
        set.add(p1);
        set.add(p2);

        for (Person person : set) {
            System.out.println(person);
        }

        //测试name()和partner():类似于getName()和getPartner()
        System.out.println(p1.name());
        System.out.println(p1.partner());

    }
}

运行结果:

很吊,但是刚才为什么说有局限性呢,来看。

优点:还可以声明静态的属性、静态的方法、构造器、实例方法

局限1:record中不可以声明非静态的属性

局限2:不可以将record定义的类声明为abstract的

局限2:不可以给record定义的类声明显式的父类(非Record类)

下面的写法都是报错的:

具体原因我们看idea反编译之后的.class文件吧。原因一目了然

语法四:switch表达式

这是JDK 12JDK 13中的预览特性,现在是正式特性了。

该特性规定,switch可以当作语句使用,也可以当作表达式使用。

具体情况:

使用 -> 来替代以前的 :+break ;另外还提供了 yield 来在 block 中返回值
上代码:
/**
 *  switch的新特性
 */
public class Feature04 {
    //jdk12之前的用法
    @Test
    public void test1() {

        Week day = Week.FRIDAY;
        switch (day) {
            case MONDAY:
            case TUESDAY:
            case WEDNESDAY:
                System.out.println(1);
                break;
            case THURSDAY:
                System.out.println(2);
                break;
            case FRIDAY:
            case SATURDAY:
                System.out.println(3);
                break;
            case SUNDAY:
                System.out.println(4);
                break;
            default:
                throw new IllegalStateException("What day is today?" + day);
        }

    }

    //jdk12新特性:引用switch表达式
    @Test
    public void test2(){

        Week day = Week.FRIDAY;
        switch (day){
            case MONDAY,TUESDAY,WEDNESDAY -> System.out.println(1);
            case THURSDAY -> System.out.println(2);
            case FRIDAY,SATURDAY -> System.out.println(3);
            case SUNDAY -> System.out.println(4);
            default -> throw new IllegalStateException("What day is today?" + day);
        }

        //使用变量接收switch表达式的值
        int num = switch (day) {
            case MONDAY, TUESDAY, WEDNESDAY -> 1;
            case THURSDAY -> 2;
            case FRIDAY, SATURDAY -> 3;
            case SUNDAY -> 4;
            default -> throw new IllegalStateException("What day is today?" + day);
        };

        System.out.println(num);

    }

    //jdk13新特性:引用了yield关键字,用于返回指定的数据,结束switch结构
    @Test
    public void test3(){
        String x = "3";
        int num = switch (x){
            case "1" -> 1;
            case "2" -> 2;
            case "3" -> 3;
            default -> {
                System.out.println("default...");
                yield 4;
            }
        };

        System.out.println(x);
    }

    @Test
    public void test4(){
        String x = "3";
        int num = switch (x){
            case "1":yield 1;
            case "2":yield 2;
            case "3":yield 3;
            default: yield 4;
        };
        System.out.println(num);
    }


}

enum Week {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

总结:

语法五:文本块(预览第二版)

什么意思?就是拼接各种字符串的时候以前是那样的,现在是这样的。哈哈

可能之前在java里面拼接html或者邮件格式等,显得格式很难看,换行什么的,不好看,现在修改了一下。看代码吧。

/**
 * 文本块(text blocks)的使用
 */
public class Feature05 {


    @Test
    public void test1(){
        //以前写法,格式是不是很不好看?
        String text1 = "The Sound of silence\n" +
                "Hello darkness, my old friend\n" +
                "I've come to talk with you again\n" +
                "Because a vision softly creeping\n" +
                "Left its seeds while I was sleeping\n" +
                "And the vision that was planted in my brain\n" +
                "Still remains\n" +
                "Within the sound of silence";

        System.out.println(text1);

        //jdk13中的新特性:
        String text2 = """
                The Sound of silence
                Hello darkness, my old friend
                I've come to talk with you again
                Because a vision softly creeping
                Left its seeds while I was sleeping
                And the vision that was planted in my brain
                Still remains
                Within the sound of silence""";
                //注意:“”“ 放在下一行和放在上一行,text1和text2长度不一样,text2长度 变长 一位
                //""";
        System.out.println();
        System.out.println(text2);
}

    //html
    @Test
    public void test2(){
        //以前写法,格式是不是很不好看?
        String html1 = "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>java14新特性</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "    <p>hello,atguigu</p>\n" +
                "</body>\n" +
                "</html>";
            //jdk13中的新特性:
        String html2 = """
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>java14新特性</title>
                </head>
                <body>
                    <p>hello,atguigu</p>
                </body>
                </html>
                """;
    }

    //json
    @Test
    public void test3() {
        //jdk13之前的写法
        String myJson = "{\n" +
                "    \"name\":\"Song Hongkang\",\n" +
                "     \"address\":\"www.atguigu.com\",\n" +
                "    \"email\":\"shkstart@126.com\"\n" +
                "}";
        System.out.println(myJson);

        //jdk13的新特性
        String myJson1 = """
                {
                    "name":"Song Hongkang",
                     "address":"www.atguigu.com",
                    "email":"shkstart@126.com"
                }""";
        System.out.println(myJson1);
    }

    //sql
    @Test
    public void test4(){
        //以前写法,格式是不是很不好看?
        String sql = "SELECT id,NAME,email\n" +
                "FROM customers\n" +
                "WHERE id > 4\n" +
                "ORDER BY email DESC";

        //jdk13新特性:
        String sql1 = """
                SELECT id,NAME,email
                FROM customers
                WHERE id > 4
                ORDER BY email DESC
                """;



    }
    //jdk14新特性
    @Test
    public void test5(){
        String sql1 = """
                SELECT id,NAME,email
                FROM customers
                WHERE id > 4
                ORDER BY email DESC
                """;
        System.out.println(sql1);

        // \:取消换行操作
        // \s:表示一个空格
        String sql2 = """
                SELECT id,NAME,email \
                FROM customers\s\
                WHERE id > 4 \
                ORDER BY email DESC
                """;
        System.out.println(sql2);
    }
}

总结:用 """  文本 """ 来搞这个字符串,显得格式不错。

语法层面就上面这些。

下面看一下jvm层面的优化。(了解)

1.弃用ParallelScavengeSerialOld GC组合

2.删除CMS垃圾回收器

3.我们还看到了引入了两个新的收集器:

ZGC (JDK11出现)和Shenandoah(非oracle出品)
 
ZGC: 以低延迟为首要目标的一款垃圾收集器。设置ZGC命令:-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
 
Shenandoah 这哥们 不是oracle团队出品,估计也活不久。
 
神一样的cms,还是被删除淘汰了。
 
还有一些其他的改动,就不一一列出了,平时基本用不到。
 

写在最后:JDK 14 性能提升,但 JDK 8 仍是最强王者!

 

感谢尚硅谷!硅谷无敌!

原创不易,转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值