JAVA【JAVA9&10&11新特性】

目录

一、JAVA9的新特性

1.目录结构的变化 

2.模块化系统

3.Java的REPL工具

/imports 

/help

/vars

自动补全

/open

/exit

4.接口的私有方法

5.钻石操作符的升级

6.try语句的升级 

 7.string存储结构的变更

8.快速创建只读集合 

9.imputstream加强

10.增强的Stream API

dropWhile()的使用

 ofNullable()的使用

 iterate重载的使用

11.Optional获取Stream的方法 

12.Javascript引擎升级Nashorn

二、JAVA10新特性

一、 局部变量类型推断 

 二、集合新增创建不可变集合的方法

三、Java11新特性

一、新增了一系列字符串处理方法

二、Optional加强

三、局部变量类型推断升级

四、全新的HTTP客户端API

五、更简化的编译运行程序

六、废弃Nashorn引擎 

七、 ZGC


一、JAVA9的新特性

从Java 9 这个版本开始, Java 的计划发布周期是 6 个月,下一个 Java 的主版本将于 2018 年 3 月发布,命名为 Java 18.3,紧接着再过六个月将发布 Java18.9。

模块化系统
jShell命令
多版本兼容jar包
接口的私有方法
钻石操作符的使用升级
语法改进: try语句
String存储结构变更
便利的集合特性: of()
增强的Stream API
全新的HTTP客户端API
Deprecated的相关API
javadoc的HTML 5支持
Javascript引擎升级: Nashorn
java的动态编译器 

1.目录结构的变化 

 

以下是我的jdk,是与Java9目录一样的。 

 

 

 

2.模块化系统

Java 运行环境的膨胀和臃肿。 每次JVM启动的时候,至少会有30~60MB的内存加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去(而模块化可以根据模块的需要加载程序运行需要的class)


        当代码库越来越大,创建复杂,盘根错节的“意大利面条式代码”的几率呈指数级的
增长。 不同版本的类库交叉依赖导致让人头疼的问题,这些都阻碍了 Java 开发和
运行效率的提升。


        很难真正地对代码进行封装, 而系统并没有对不同部分(也就是 JAR 文件)之间
的依赖关系有个明确的概念。 每一个公共类都可以被类路径之下任何其它的公共
类所访问到,这样就会导致无意中使用了并不想被公开访问的 API。

        本质上讲也就是说, 用模块来管理各个package,通过声明某个package暴露, ,模块(module)的概念,其实就是package外再裹一层, 不声明默认就是隐藏。因此,模块化使得代码组织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏。

这是我们的文件目录

首先我们在一个模块中暴露我们自身的模块

就是在下面这个文件中写入下列代码

 

 

 

然后我们在另一个模块中接收我们前面暴露的模块

 在我们之前暴露的包中我们定义了如下的person类

package com.zhuyuan.bean;

public class Person {

    private String name;
    private int age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

然后我们在接收的那个模块中就可以调用这个模块的person类了

package com.zhuyuan.java;

import com.zhuyuan.bean.Person;

/**
 * @author shkstart
 * @create 2019 上午 11:59
 */
public class ModuleTest {

    public static void main(String[] args) {
        Person p = new Person("催逝员",12);
        System.out.println(p);
    }

}

 

3.Java的REPL工具

产生背景
像Python 和 Scala 之类的语言早就有交互式编程环境 REPL (read - evaluate - print -loop)了, 以交互式的方式对语句和表达式进行求值。 开发者只需要输入一些代码,就可以在编译前获得对程序的反馈。 而之前的Java版本要想执行代码, 必须创建文件、 声明类、 提供测试方法方可实现。


设计理念
即写即得、 快速运行


实现目标
Java 9 中终于拥有了 REPL工具: jShell。 让Java可以像脚本语言一样运行,从控制台启动jShell, 利用jShell在没有创建类的情况下直接声明变量,计算表达式,执行语句。即开发时可以在命令行里直接运行Java的代码,而无需创建Java文件,无需跟人解释” public static void main(String[] args)”这句废话。 jShell也可以从文件中加载语句或者将语句保存到文件中。jShell也可以是tab键进行自动补全和自动添加分号。调出jShell
获取帮助

我们的jshell就在我们的这个路径下

 我们可以打开终端,输入jshell

 

在jshell里面我们可以直接输入Java的代码并且运行

 

 

 可以定义变量进行运算

 可以定义函数进行运算

 可以定义类

 如果我们的代码写错了可以输入/edit来对我们刚刚的代码进行重新编辑

 可以创建类对应的对象然后调用其中的方法

/imports 

使用/imports可以查看目前已经导入了哪些包

/help

使用/help可以获得具体的方法的帮助

 

/vars

使用/vars查看我们已经定义过的正确的变量,使用/methods查看我们当前已经定义过的方法,使用/list查看我们已经定义过的数据列表。jshell是支持重复定义的,后面定义的会覆盖之前定义的对应的数值或者方法。

 

自动补全

使用tab键可以自动补全,注意只有匹配到唯一选项才会自动填充,没有匹配到唯一选项之前会将全部的待匹配选项都列出来。

/open

我们也可以使用jshell去运行我们已经做好的java文件

这里我们有一个helloworld文件

在我们的终端使用/open空格,再加上我们文件路径,就可以运行我们对应的文件

 

 

jshell没有受检异常(编译时异常),因为jshell在后台为我们隐藏了

/exit

退出jshell

 

4.接口的私有方法

 Java 8中规定接口中的方法除了抽象方法之外, 还可以定义静态方法和默认的方法。 一定程度上, 扩展了接口的功能, 此时的接口更像是一个抽象类。


在Java 9中, 接口更加的灵活和强大, 连方法的访问权限修饰符都可以声明为private的了, 此时方法将不会成为你对外暴露的API的一部分。

public interface MyInterface {
    //如下的三个方法的权限修饰符都是public
    void methodAbstract();

    static void methodStatic(){
        System.out.println("我是接口中的静态方法");
    }

    default void methodDefault(){
        System.out.println("我是接口中的默认方法");

        methodPrivate();
    }
    //jdk 9中允许接口中定义私有的方法
    private void methodPrivate(){
        System.out.println("我是接口中的私有方法");
    }
}
public class MyInterfaceImpl implements MyInterface {


    @Override
    public void methodAbstract() {

    }

//    @Override
    public void methodDefault() {
        System.out.println("实现类重写了接口中的默认方法");
    }

    public static void main(String[] args) {
        //接口中的静态方法只能由接口自己调用
        MyInterface.methodStatic();
        //接口的实现类不能调用接口的静态方法
//        MyInterfaceImpl.methodStatic();

        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.methodDefault();
        //接口的私有方法,不能在接口外部调用
//        impl.methodPrivate();
    }
}

5.钻石操作符的升级

钻石操作符也就是我们的泛型<>

//java9特性五:钻石操作符的升级
    @Test
    public void test2() {
        //钻石操作符与匿名内部类在java 8中不能共存。在java9可以。
        Comparator<Object> com = new Comparator<>() {
            @Override
            public int compare(Object o1, Object o2) {
                return 0;
            }
        };

        //jdk7中的新特性:类型推断
        ArrayList<String> list = new ArrayList<>();

    }

6.try语句的升级 

这是我们Java8之前的资源关闭的操作,也就是我们的资源关闭通常是放在finally当中的。

//java9 特性六:try操作的升级
    public static void main(String[] args) {
        //java 8之前的资源关闭的操作
        InputStreamReader reader = null;
        try {
            reader = new InputStreamReader(System.in);
            char[] cbuf = new char[20];
            int len;
            if((len = reader.read(cbuf) )!= -1){
                String str = new String(cbuf,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(reader != null){
                try {
                    //资源的关闭
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }

 以下是在Java8中的资源关闭操作

//java 8中资源关闭操作: Java 8 中,可以实现资源的自动关闭
        //要求自动关闭的资源的实例化必须放在try的一对小括号中
        try(InputStreamReader reader = new InputStreamReader(System.in)){
            char[] cbuf = new char[20];
            int len;
            if((len = reader.read(cbuf) )!= -1){
                String str = new String(cbuf,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

以下是Java9中的资源关闭操作 

//java9中资源关闭操作:需要自动关闭的资源的实例化可以放在try的一对小括号外。
        //此时的资源属性是常量,声明为final的,不可修改
        InputStreamReader reader = new InputStreamReader(System.in);
        try (reader) {

            char[] cbuf = new char[20];
            int len;
            if((len = reader.read(cbuf) )!= -1){
                String str = new String(cbuf,0,len);
                System.out.println(str);
            }

//            reader = null;
        } catch (IOException e) {
            e.printStackTrace();
        }

 

 7.string存储结构的变更

Motivation
The current implementation of the String class stores characters in a char array, using two bytes (sixteen bits) for each character. Data gathered from many different applications indicates that strings are a major component of heap usage and, moreover, that most String objects contain only Latin-1 characters. Such characters require only one byte of storage, hence half of the space in the internal char arrays of such String objects is going unused.


Description
We propose to change the internal representation of the String class from a UTF-16 char array to a byte array plus an encoding-flag field. The new String class will store characters encoded either as ISO-8859-1/Latin-1 (one byte per character), or as UTF-16 (two bytes per character), based upon the contents of the string. The encoding flag will indicate which encoding is used.

结论: String 再也不用 char[] 来存储, 改成了 byte[] 加上编码标记, 节约了一些空间。

StringBuffer 和 StringBuilder 同样也发生了变化

String-related classes such as AbstractStringBuilder, StringBuilder,and StringBuffer will be updated to use the same representation, as will the HotSpot VM‘s intrinsic(固有的、内置的) string operations 

8.快速创建只读集合 

Java8创建只读集合的方法,下面的代码中我们通过unmodifiablelist将我们的nameslist转换为一个只读集合,所以是不能够再被改变的,在我们后面试图加入tom的时候会报错

 //java8中的写法:
    @Test
    public void test1() {
        List<String> namesList = new ArrayList<>();
        namesList.add("Joe");
        namesList.add("Bob");
        namesList.add("Bill");
        //返回的namesList是一个只读的集合
        namesList = Collections.unmodifiableList(namesList);
        namesList.add("Tom");

        System.out.println(namesList);

    }
@Test
    public void test3() {
        //此时得到的集合list也是一个只读集合。
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        //报异常
        list.add(6);

    }

从原码中我们可以看出此方法调用的是一个static也就是静态的ArrayList

 

Java9创建只读集合的方法 

//java9新特性八:集合工厂方法:创建只读集合
    @Test
    public void test4() {
        List<Integer> list1 = List.of(1, 2, 3, 4, 5);
        //不能添加
//        list1.add(6);
        System.out.println(list1);

        Set<Integer> set1 = Set.of(23, 3, 54, 65, 43, 76, 87, 34, 46);
        //不能添加
//        set1.add(4);
        System.out.println(set1);

        Map<String, Integer> map1 = Map.of("薛总司令", 23, "催逝员", 54, "王大队长", 12);
        //不能添加
        //map1.put("Lilei",34);

        System.out.println(map1);

        Map<String, Integer> map2 = Map.ofEntries(Map.entry("华强", 34), Map.entry("瓜老板", 21));
//        map2.put("Lilei",34);
        System.out.println(map2);


    }

 

 

9.imputstream加强

InputStream 终于有了一个非常有用的方法: transferTo,可以用来将数据直接传输到 OutputStream,这是在处理原始数据流时非常常见的一种用法,如下示例。

@Test
    public void test5() {
        ClassLoader cl = this.getClass().getClassLoader();
        try (InputStream is = cl.getResourceAsStream("hello.txt");
             OutputStream os = new FileOutputStream("src\\hello1.txt")) {
            is.transferTo(os); // 把输入流中的所有数据直接自动地复制到输出流中
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

10.增强的Stream API

 java 的 Steam API 是java标准库最好的改进之一, 让开发者能够快速运算,从而能够有效的利用数据并行计算。 Java 8 提供的 Steam 能够利用多核架构实现声明式的数据处理。
        在 Java 9 中, Stream API 变得更好, Stream 接口中添加了 4 个新的方法:
takeWhile, dropWhile, ofNullable,还有个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。
        除了对 Stream 本身的扩展, Optional 和 Stream 之间的结合也得到了改进。现在可以通过 Optional 的新方法 stream() 将一个 Optional 对象转换为一个(可能是空的) Stream 对象。

takeWhile()的使用
用于从 Stream 中获取一部分数据, 接收一个 Predicate 来进行选择。 在有序的Stream 中, takeWhile 返回从开头开始的尽量多的元素 

dropWhile()的使用

dropWhile 的行为与 takeWhile 相反, 返回剩余的元素

//java9新特性十:Stream API的加强
    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(23, 43, 45, 55, 61, 54, 32, 2, 45, 89, 7);
        //takeWhile 返回从开头开始的按照指定规则尽量多的元素
//        list.stream().takeWhile(x -> x < 60).forEach(System.out::println);
        //dropWhile():与 takeWhile 相反,返回剩余的元素。
        list.stream().dropWhile(x -> x < 60).forEach(System.out::println);
    }

 

 ofNullable()的使用

Java 8 中 Stream 不能完全为null, 否则会报空指针异常。 而 Java 9 中的 ofNullable 方法允许我们创建一个单元素 Stream, 可以包含一个非空元素, 也可以创建一个空Stream。 

@Test
    public void test2(){
        //of()参数中的多个元素,可以包含null值
        Stream<Integer> stream1 = Stream.of(1, 2, 3,null);
        stream1.forEach(System.out::println);
        //of()参数不能存储单个null值。否则,报异常
//        Stream<Object> stream2 = Stream.of(null);
//        stream2.forEach(System.out::println);
        Integer i = 10;
        i = null;
        //ofNullable():形参变量是可以为null值的单个元素
        Stream<Integer> stream3 = Stream.ofNullable(i);
        long count = stream3.count();
        System.out.println(count);
    }

 

 iterate重载的使用

这个 iterate 方法的新重载方法, 可以让你提供一个 Predicate (判断条件)来指定什
么时候结束迭代。

@Test
    public void test3(){

        Stream.iterate(0,x -> x + 1).limit(10).forEach(System.out::println);


        //java9中新增的重载的方法
        Stream.iterate(0,x -> x < 100,x -> x + 1).forEach(System.out::println);
    }

11.Optional获取Stream的方法 

 Optional类中stream()的使用

@Test
    public void test4(){
        List<String> list = new ArrayList<>();
        list.add("Tom");
        list.add("Jerry");
        list.add("Tim");

        Optional<List<String>> optional = Optional.ofNullable(list);
        Stream<List<String>> stream = optional.stream();
//        long count = stream.count();
//        System.out.println(count);
        stream.flatMap(x -> x.stream()).forEach(System.out::println);

    }

 

12.Javascript引擎升级Nashorn

Nashorn 项目在 JDK 9 中得到改进, 它为 Java 提供轻量级的 Javascript 运行时。Nashorn 项目跟随 Netscape 的 Rhino 项目, 目的是为了在 Java 中实现一个高性能但轻量级的 Javascript 运行时。 Nashorn 项目使得 Java 应用能够嵌入Javascript。 它在 JDK 8 中为 Java 提供一个 Javascript 引擎。


JDK 9 包含一个用来解析 Nashorn 的 ECMAScript 语法树的 API。 这个 API 使得IDE 和服务端框架不需要依赖 Nashorn 项目的内部实现类, 就能够分析ECMAScript 代码。

二、JAVA10新特性

2018年3月21日, Oracle官方宣布Java10正式发布。
        需要注意的是 Java 9 和 Java 10 都不是 LTS (Long-Term-Support) 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本。
        JDK10一共定义了109个新特性, 其中包含12个JEP(对于程序员来讲, 真正的新特性其实就一个) , 还有一些新API和JVM规范以及JAVA语言规范上的改动。
        JDK10的12个JEP(JDK Enhancement Proposal特性加强提议) 参阅官方文档: http://openjdk.java.net/projects/jdk/10/

286: Local-Variable Type Inference 局部变量类型推断
296: Consolidate the JDK Forest into a Single Repository JDK库的合并
304: Garbage-Collector Interface 统一的垃圾回收接口
307: Parallel Full GC for G1 为G1提供并行的Full GC
310: Application Class-Data Sharing 应用程序类数据(AppCDS)共享
312: Thread-Local Handshakes ThreadLocal握手交互
313: Remove the Native-Header Generation Tool (javah) 移除JDK中附带的javah工具
314: Additional Unicode Language-Tag Extensions 使用附加的Unicode语言标记扩展
316: Heap Allocation on Alternative Memory Devices 能将堆内存占用分配给用户指定的备用内存设备
317: Experimental Java-Based JIT Compiler 使用基于Java的JIT编译器
319: Root Certificates 根证书
322: Time-Based Release Versioning 基于时间的发布版本 

一、 局部变量类型推断 

产生背景
        开发者经常抱怨Java中引用代码的程度。 局部变量的显示类型声明,常常被认为是不必须的,给一个好听的名字经常可以很清楚的表达出下面应该怎样继续。
好处:
减少了啰嗦和形式的代码,避免了信息冗余,而且对齐了变量名,更容易阅读!

举例如下:
场景一: 类实例化时
        作为 Java开发者, 在声明一个变量时, 我们总是习惯了敲打两次变量类型, 第
一次用于声明变量类型, 第二次用于构造器。 

LinkedHashSet<Integer> set = new LinkedHashSet<>();

场景二: 返回值类型含复杂泛型结构

变量的声明类型书写复杂且较长,尤其是加上泛型的使用

Iterator<Map.Entry<Integer, Student>> iterator = set.iterator();

场景三:
我们也经常声明一种变量, 它只会被使用一次, 而且是用在下一行代码中,比如:

URL url = new URL("http://www.baidu.com");
URLConnection connection = url.openConnection();
Reader reader = new BufferedReader(new
InputStreamReader(connection.getInputStream()));

尽管 IDE可以帮我们自动完成这些代码,但当变量总是跳来跳去的时候,可读性还是会受到影响,因为变量类型的名称由各种不同长度的字符组成。而且,有时候开发人员会尽力避免声明中间变量,因为太多的类型声明只会分散注意力,不会带来额外的好处。

 @Test
    public void test1() {
        //1.声明变量时,根据所附的值,推断变量的类型
        var num = 10;

        var list = new ArrayList<Integer>();
        list.add(123);

        //2.遍历操作
        for (var i : list) {
            System.out.println(i);
            System.out.println(i.getClass());
        }

        //3.普通的遍历操作
        for (var i = 0; i < 100; i++) {
            System.out.println(i);
        }

    }

在下面的情况中,类型推断是不适用的 

@Test
    public void test2() {
        //1.局部变量不赋值,就不能实现类型推断
//        var num ;

        //2.lambda表示式中,左边的函数式接口不能声明为var
//        Supplier<Double> sup = () -> Math.random();

//        var sup = () -> Math.random();

        //3.方法引用中,左边的函数式接口不能声明为var
//        Consumer<String> con = System.out::println;

//        var con = System.out::println;

        //4.数组的静态初始化中,注意如下的情况也不可以
        int[] arr = {1, 2, 3, 4};
//        var arr = {1,2,3,4};
    }
 @Test
    public void test3() {
//        情况1:没有初始化的局部变量声明
//        var s = null;


//        情况6:catch块
//        try{
//
//        }catch(var e){
//            e.printStackTrace();
//        }


    }
    //情况2:方法的返回类型
//    public var method1(){
//
        return 0;
//    }
    // 情况3:方法的参数类型
//    public void method2(var num){
//
//    }

    //情况4:构造器的参数类型
//    public Java10Test(var i){
//
//    }

    //情况5:属性
//    var num;

工作原理:

在处理 var时, 编译器先是查看表达式右边部分, 并根据右边变量值的类型进行推断, 作为左边变量的类型, 然后将该类型写入字节码当中。

注意:

1.var不是一个关键字
        你不需要担心变量名或方法名会与 var发生冲突, 因为 var实际上并不是一个关键字,而是一个类型名, 只有在编译器需要知道类型的地方才需要用到它。 除此之外, 它就是一个普通合法的标识符。 也就是说, 除了不能用它作为类名, 其他的都可以,但极少人会用它作为类名。

2.这不是JavaScript
        首先我要说明的是, var并不会改变Java是一门静态类型语言的事实。 编译器负责推
断出类型, 并把结果写入字节码文件, 就好像是开发人员自己敲入类型一样。下面是使用 IntelliJ(实际上是 Fernflower的反编译器)反编译器反编译出的代码:

下面的代码对于局部变量类型推断的使用是正确的 

@Test
    public void test4() {
        try {
            var url = new URL("http://www.baidu.com");
            var connection = url.openConnection();
            var reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

 二、集合新增创建不可变集合的方法

自 Java 9 开始, Jdk 里面为集合(List / Set / Map) 都添加了 of (jdk9新增)和copyOf (jdk10新增)方法, 它们两个都用来创建不可变的集合, 来看下它们的使用和区别。

//java10的新特性二:集合中新增的copyOf(),用于创建一个只读的集合
    @Test
    public void test5(){
        //示例1:
        var list1 = List.of("Java", "Python", "C");
        var copy1 = List.copyOf(list1);
        System.out.println(list1 == copy1); // true

        //示例2:
        var list2 = new ArrayList<String>();
        list2.add("aaa");
        var copy2 = List.copyOf(list2);
        System.out.println(list2 == copy2); // false

        //示例1和2代码基本一致,为什么一个为true,一个为false?
        //结论:copyOf(Xxx coll):如果参数coll本身就是一个只读集合,则copyOf()返回值即为当前的coll
        //如果参数coll不是一个只读集合,则copyOf()返回一个新的集合,这个集合是只读的。

    }

 

三、Java11新特性

北京时间 2018年9 月 26 日,Oracle 官方宣布 Java 11 正式发布。 这是 Java 大版本周期变化后的第一个长期支持版本, 非常值得关注。 从官网即可下载,最新发布的 Java11 将带来 ZGC、Http Client 等重要特性, 一共包含 17 个重要的 JEP(JDK EnhancementProposals, JDK 增强提案) 。 

        对于企业来说, 选择 11 将意味着长期的、 可靠的、 可预测的技术路线图。其中免费的OpenJDK11 确定将得到 OpenJDK 社区的长期支持, LTS 版本将是可以放心选择的版本。


        从 JVM GC 的角度, JDK11 引入了两种新的 GC, 其中包括也许是划时代意义的 ZGC, 虽然其目前还是实验特性, 但是从能力上来看, 这是 JDK 的一个巨大突破, 为特定生产环境的苛刻需求提供了一个可能的选择。 例如, 对部分企业核心存储等产品, 如果能够保证不超过 10ms 的 GC 暂停, 可靠性会上一个大的台阶, 这是过去我们进行 GC 调优几乎做不到的, 是能与不能的问题。 

        新的长期支持版本每三年发布一次,根据后续的发布计划,下一个长期支持版 Java 17 将于2021年发布。

官网公开的17个JEP (JDK Enhancement Proposal 特性增强提议)

181: Nest-Based Access Control(基于嵌套的访问控制)
309: Dynamic Class-File Constants(动态的类文件常量)
315: Improve Aarch64 Intrinsics(改进 Aarch64 Intrinsics)
318: Epsilon: A No-Op Garbage Collector( Epsilon 垃圾回收器,又被称为"No-Op(无操作回收器,又被称为"No-Op(无操作)"回收器)
320: Remove the Java EE and CORBA Modules(移除 Java EE 和 CORBA 模块, JavaFX
也已被移除)
321: HTTP Client (Standard)
323: Local-Variable Syntax for Lambda Parameters(用于 Lambda 参数的局部变量语法)
324: Key Agreement with Curve25519 and Curve448(采用 Curve25519 和 Curve448 算法实现的密钥协议) 

327: Unicode 10
328: Flight Recorder(飞行记录仪)
329: ChaCha20 and Poly1305 Cryptographic Algorithms(实现 ChaCha20 和 Poly1305 加密算法)
330: Launch Single-File Source-Code Programs(启动单个 Java 源代码文件的程序)
331: Low-Overhead Heap Profiling(低开销的堆分配采样方法)
332: Transport Layer Security (TLS) 1.3(对 TLS 1.3 的支持)
333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)( ZGC:可伸缩的低延迟垃圾回收器,处于实验性阶段)
335: Deprecate the Nashorn JavaScript Engine(弃用 Nashorn JavaScript 引擎)
336: Deprecate the Pack200 Tools and API(弃用 Pack200 工具及其 API)

一、新增了一系列字符串处理方法

 

//java 11新特性一:String中新增的方法
    @Test
    public void test1(){
//        isBlank():判断字符串是否为空白
        System.out.println("  \t  \t  \n  ".isBlank());
//        strip():去除首尾空白
        System.out.println("-----" + "  \t abc \t  \n  ".strip() + "-------");
        System.out.println("-----" + "  \t abc \t  \n  ".trim() + "-------");
//        stripTrailing():去除尾部空格
        System.out.println("-----" + "  \t abc \t  \n  ".stripTrailing() + "-------");
//        stripLeading():去除首部空格
        System.out.println("-----" + "  \t abc \t  \n  ".stripLeading() + "-------");
//        repeat(int count):复制字符串
        String str1 = "abc";
        String str2 = str1.repeat(5);
        System.out.println(str2);

//        lines().count():行数统计
        String str3 = "abc\ndef\ng";
        System.out.println(str3.lines().count());


    }

二、Optional加强

Optional 也增加了几个非常酷的方法, 现在可以很方便的将一个 Optional 转换成一个 Stream, 或者当一个空 Optional 时给它一个替代的。

//java11新特性二:Optional新增的方法
    @Test
    public void test2(){

        var op = Optional.empty();
        System.out.println(op.isPresent());//判断内部的value是否存在
        System.out.println(op.isEmpty());//判断内部的value是否为空

        op = Optional.of("abc");
        //orElseThrow():value非空,返回value;否则抛异常NoSuchElementException
        var obj = op.orElseThrow();
        System.out.println(obj);

        Optional<String> op1 = Optional.of("hello");
//        op = Optional.empty();
        //or:value非空,返回对应的Optional;value为空,返回形参封装的Optional
        Optional<Object> op2 = op.or(() -> op1);
        System.out.println(op2);//

    }

 

三、局部变量类型推断升级

在var上添加注解的语法格式,在jdk10中是不能实现的。在JDK11中加入了这样的语法。

//java11新特性三:局部变量类型推断的升级
    @Test
    public void test3(){
        //错误的形式: 必须要有类型, 可以加上var
        //用注解去修饰变量的时候,类型一定是要有的,
//        Consumer<String> con1 = (@Deprecated t) -> System.out.println(t.toUpperCase());
        // 正确的形式:
        // 使用var的好处是在使用lambda表达式时给参数加上注解。
         Consumer<String> con2 = (@Deprecated var t) -> System.out.println(t.toUpperCase());

    }

四、全新的HTTP客户端API

HTTP,用于传输网页的协议,早在1997年就被采用在目前的1.1版本中。直到2015年, HTTP2才成为标准。

HTTP/1.1和HTTP/2的主要区别是如何在客户端和服务器之间构建和传输数据。
HTTP/1.1依赖于请求/响应周期。 HTTP/2允许服务器“push”数据:它可以发送比客户端请求更多的数据。 这使得它可以优先处理并发送对于首先加载网页至关重要的数据。
        

这是 Java 9 开始引入的一个处理 HTTP 请求的的 HTTP Client API, 该
API 支持同步和异步, 而在 Java 11 中已经为正式可用状态, 你可以在
java.net 包中找到这个 API。

它 将 替 代 仅 适 用 于 blocking 模 式 的 HttpURLConnection( HttpURLConnection是在HTTP 1.0的时代创建的, 并使用了协议无关的方法) , 并提供对WebSocket 和 HTTP/2的支持。

//java11新特性四:HttpClient替换原有的HttpURLConnection。
    @Test
    public void test4(){
        try {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/test/")).build();
            HttpResponse.BodyHandler<String> responseBodyHandler = HttpResponse.BodyHandlers.ofString();
            HttpResponse<String> response = client.send(request, responseBodyHandler);
            String body = response.body();
            System.out.println(body);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
@Test
    public void test5(){
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder(URI.create("http://127.0.0.1:8080/test/")).build();
        HttpResponse.BodyHandler<String> responseBodyHandler = HttpResponse.BodyHandlers.ofString();
        CompletableFuture<HttpResponse<String>> sendAsync = client.sendAsync(request, responseBodyHandler);
        sendAsync.thenApply(t -> t.body()).thenAccept(System.out::println);
        //HttpResponse<String> response = sendAsync.get();
        //String body = response.body();
        //System.out.println(body);


    }

五、更简化的编译运行程序

看下面的代码。
// 编译
javac Javastack.java
// 运行
java Javastack
在我们的认知里面, 要运行一个 Java 源代码必须先编译, 再运行, 两步执行动作。而在未来的 Java 11 版本中, 通过一个 java 命令就直接搞定了, 如以下所示:
java Javastack.java
一个命令编译运行源代码的注意点:
        执行源文件中的第一个类, 第一个类必须包含主方法。
        并且不可以使用其它源文件中的自定义类, 本文件中的自定义类是可以使用的。

六、废弃Nashorn引擎 

废除Nashorn javascript引擎, 在后续版本准备移除掉, 有需要的可以考虑使用GraalVM。

七、 ZGC

GC是java主要优势之一。 然而, 当GC停顿太长, 就会开始影响应用的响应时间。 消除或者减少GC停顿时长, java将对更广泛的应用场景是一个更有吸引力的平台。 此外, 现代系统中可用内存不断增长,用户和程序员希望JVM能够以高效的方式充分利用这些内存, 并且无需长时间的GC暂停时间。

ZGC, A Scalable Low-Latency Garbage Collector(Experimental)ZGC, 这应该是JDK11最为瞩目的特性, 没有之一。 但是后面带了Experimental,说明这还不建议用到生产环境。
 

ZGC是一个并发, 基于region, 压缩型的垃圾收集器, 只有root扫描阶段会STW(stop the world), 因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。

优势:
        GC暂停时间不会超过10ms
        既能处理几百兆的小堆, 也能处理几个T的大堆(OMG)
        和G1相比, 应用吞吐能力不会下降超过15%
        为未来的GC功能和利用colord指针以及Load barriers优化奠定基础
        初始只支持64位系统


        ZGC的设计目标是:支持TB级内存容量, 暂停时间低(<10ms) , 对整个程序吞吐量的影响小于15%。 将来还可以扩展实现机制, 以支持不少令人兴奋的功能, 例如多层堆(即热对象置于DRAM和冷对象置于NVMe闪存),或压缩堆。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存工具 SimpleCache SimpleCache 是一个简单易用的java缓存工具,用来简化缓存代码的编写,让你摆脱单调乏味的重复工作!1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后端缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. 支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是一个用来操作Windows注册表的 Java 类库,你可以用来对注册表信息进行读写。 GIF动画制作工具 GiftedMotion GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端 JOpenID JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桜キャンドル淵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值