栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

从 Java8 到 Java11 再到 Java17 的新特性(3)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从 Java8 到 Java11 再到 Java17 的新特性(3)

2021年9月14日甲骨文正式发布 Java 17,这是继 Java11 之后的又一个 LTS 版本,而且 Oracle 开始提供免费使用的许可证,并在下一个 LTS 版本之后继续提供整整一年。所以还是有限制的,一般我们都用 OpenJDK 得了,来看看 Java12 到 17 提供了哪些新的语言特性和 API。

本文源码地址:code-note

1. Switch 表达式

在 Java 12(12、13预览,14正式) 之后,对 Switch 表达式进行了改进,比传统写法更简便,在 Java17 的预览版中,还支持对类型的匹配。

public class SwitchExample {

    
    @Test
    public void switchBeforeTest() {
        Character c= 'B';
        String res;
        switch (c) {
            case 'A':
                res = "优秀";
                break;
            case 'B':
                res = "良好";
                break;
            case 'C':
                res = "及格";
                break;
            default:
                res = "未知等级";
        }
        Assert.assertEquals("良好", res);
    }

    
    @Test
    public void switchNowTest() {
        var c = 'B';
        var res = switch (c) {
            case 'A' -> "优秀";
            case 'B' -> "良好";
            case 'C' -> "及格";
            default -> "未知等级";
        };
        Assert.assertEquals("良好", res);
    }

    
    @Test
    public void formatTest() {
        Object o = 1000000000;
        String formatted = switch (o) {
            //相当于 if (o instanceof Integer && (int)o > 10)
            case Integer i && i > 10 -> String.format("a large Integer %d", i);
            case Integer i -> String.format("a small Integer %d", i);
            case Long l    -> String.format("a Long %d", l);
            default        -> o.toString();
        };
        System.out.println(formatted);
    }
}
2. Record 值类型

从 Java14(14、15预览,16正式)之后,可以使用 record 定义不可变数据类,用于在类和应用程序之间的数据传输(DTO 类),通过构造函数创建对象,JVM 会自动生成 getter 方法供使用,有点类似于 Lombok 的作用。区别是 Lombok 只是生成代码,而 record 类型的类附加了不可变且透明的语义,这既是优点也是缺点。Record 类不能存在任何隐藏状态,适用于作为标准化的类使用,不适合作为一个普通的 java bean 使用,更不用说代替 Lombok(可以看参考中关于 Record 与 Lombok 和 Kotlin 的 Data Classes 的比较)。

public class RecordClassExample {

    @Test
    public void recordTest() {
        var user = new User(1, "nathan", 25);
        Assert.assertEquals(1, user.id());
        Assert.assertEquals("nathan", user.username());
        Assert.assertEquals(25, user.age());
        //User[id=1, username=nathan, age=25]
        System.out.println(user);
    }

}


record User(long id, String username, int age) {
    //private int otherInt;
    
    //明确声明全部参数的构造器
    
    //全参数构造器简化写法
    
    //其他构造器要明确调用其他已定义构造器,最后调用最底层还是声明全部参数的构造器
    public User(){
        this(1, "nathan", 25);
    }
}
3. sealed 修饰封闭类

在一般情况,如果一个类没有被 final 关键字修饰,那么其他类就可以继承该类。从 Java15(15、16预览,17正式) 开始,可以使用 sealed 修饰一个类或接口,并通过 permits 指定哪几个类可以从该类继承,继承的子类必须使用 final 或者 non-sealed 修饰。

//接口也可以 sealed interface Animal permits Cat, Dog {
abstract sealed class Animal permits Cat, Dog {
    void eat() {
        System.out.println("have a meal.");
    }
    abstract void speak();
}
//需要明确用 final 修饰
final class Cat extends Animal {
    @Override
    void speak() {
        System.out.println("miao");
    }
}
//如果想被继承的话用 non-sealed 修饰
non-sealed class Dog extends Animal {
    @Override
    void speak() {
        System.out.println("wang");
    }
}

class Husky extends Dog {
    @Override
    void speak() {
        System.out.println("Stupid humans!");
    }
}
4. instanceof 模式匹配

Java 14(14、15预览,16正式) 中,对 instanceof 模式匹配做了改进,允许程序中的逻辑判断从对象中有条件地提取组件,以编写更简洁和安全的表达式。

public class InstanceofExample {

    @Test
    public void instanceofTest() {
        Object obj = "string value";
        //传统写法
        if (obj instanceof String) {
            String str = (String) obj;
            Assert.assertEquals(str, obj);
        }
        //新写法
        if (obj instanceof String s) {
            Assert.assertEquals(s, obj);
        }
        //还可以做其他操作
        if (obj instanceof String s && s.contains("val")) {
            Assert.assertEquals(s, obj);
        }
    }

}
5. 文本块

Java 13(13、14预览,15正式) 引入了文本块来解决多行文本的问题,文本块主要以三重双引号开头,并以同样的以三重双引号结尾终止,Java 14 在 Java 13 引入的文本块的基础之上,新加入了两个转义符 和 s,分别用于阻止插入换行符和避免末尾空白字符被去掉。文本块增强了使用 String 来表达 HTML、XML、SQL 或 JSON 等格式字符串的编码可读性,且易于维护。

public class TextBlocksExample {

    @Test
    public void strTest() {
        //换行
        var str = """
                Hello World!
                Java 17 is now available!
                """;
        System.out.println(str);
    }

    @Test
    public void blankTest() {
        
        var str = """
                Hello World!
                Java 17 is now available!    s
                """;
        System.out.println(str);
    }

    @Test
    public void jsonStrTest() {
        //有引号也不需要转义
        var str = """
                {
                    id: 1,
                    username: "nathan",
                    age: 25
                }
                """;
        System.out.println(str);
    }

    @Test
    public void htmlStrTest() {
        var str = """
                
                    
                       

Java 17 is now available!

"""; System.out.println(str); } }
6. stream

Java 16 引入 Stream.toList() 为更方便的添加集合方法(取代以前的 .collect(Collectors.toList()) ), 还有 Stream.mapMulti 方法,允许用多个元素替换流中的元素。

@Test
public void streamTest() {
    //.toList() 代替 .collect(Collectors.toList())
    Stream.of(1, 2, 3, 4, 5)
            .filter(i -> i % 2 == 0)
            //.count(Collectors.toList())
            .toList()
            .forEach(System.out::println);

    //mapMulti 用多个元素替换流中的元素,原来 flatMap 也能实现
    Stream.of(1, 2, 3)
            //.flatMap(num -> Stream.of(num + num, num * num, " "))
            .mapMulti((num, downstream) -> {
                downstream.accept(num + num);
                downstream.accept(num * num);
                downstream.accept(" ");
            })
            .forEach(System.out::print);
}
7. 参考
  • [1] A categorized list of all Java and JVM features since JDK 8 to 17
  • [2] Java 全栈知识体系
  • [3] 甲骨文正式发布Java 17
  • [4] Why Java’s Records Are Better* Than Lombok’s @Data and Kotlin’s Data Classes
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459715.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号