10分钟了解JDK11新特性

Posted 计算机ISO

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10分钟了解JDK11新特性相关的知识,希望对你有一定的参考价值。

JDK11新特性

JEP181:基于嵌套的访问控制

摘要:在private、public、protected的基础上,JVM又提供了新的访问控制机制:Nest;

目标:如果你的一个类中嵌套多个字累,那么子类可以访问彼此的私有成员

public class NestAccessExample {

   public static class Nest1 {
       void test() throws Exception{
           Nest2 nest2 = new Nest2();
           nest2.id = 1;
           Field field = Nest2.class.getDeclaredField("id");
           //在JDK11之前,可以设置该私有变量允许为true强行访问,默认false;
//           field.setAccessible(true);
           field.setInt(nest2, 1000);
      }
  }

   private static class Nest2 {
       private int id;
  }

   public static void main(String[] args) throws Exception {
       new Nest1().test();
  }
}
  • 当使用jdk8进行反射嵌套访问时,类中私有成员是不能被访问的

  • 特殊处理,对该字段强行允许

10分钟了解JDK11新特性

  • JDK11后多了Nest访问权限,类中私有类的成员可以访问

10分钟了解JDK11新特性


JEP309:动态类文件常量

摘要:增加一个常量类型 - CONSTANT_Dynamic

目的:降低开发新形式的可实现类文件约束带来的成本和干扰

public class DynamicTest {
   
   public static void main(String[] args) throws Throwable {
       MethodHandles.Lookup lookup = MethodHandles.lookup();
       MethodHandle methodHandle = lookup.findStatic(
               DynamicTest.class,"test",
       MethodType.methodType(void.class));
       methodHandle.invokeExact();

  }

   private static void test() {
       System.out.println("Hello World!");
  }

}

JEP315:改进Aarch64内联函数

摘要:改进现有的字符串和数组函数,并在Aarch64处理器上为java.lang.Math sin cos和log函数实现新的内联函数

目标:专用的CPU架构可提高应用程序的性能

public class Aarch64Example {

   private static void MathOnJdk11() {
       long startTime = System.nanoTime();
       for (int i = 0; i < 10000000; ++i) {
           Math.sin(i);
           Math.cos(i);
           Math.log(i);
      }
       long endTime = System.nanoTime();
       System.out.println(TimeUnit.NANOSECONDS.toMillis(endTime - startTime) + "ms");
  }

   public static void main(String[] args) {
       // JDK11运行三次:1259ms、1298ms、1225ms
       // JDK8运行三次:8507ms、8451ms、8410ms
       MathOnJdk11();

  }

}

JEP321:标准HTTP客户端

摘要:在JDK9中就应该引入了HTTPClient,不过一直处于孵化状态,到了JDK11,HTTPClient API结束了孵化状态,作为一个标准的API提供在java.net.http中

目标:取代HttpURLConnection

public class HttpClientExample {

   /**
    * 通过get
    * @param uri
    * @throws Exception
    */
   private static void syncGet(String uri) throws Exception{
       HttpClient client = HttpClient.newHttpClient();
       HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)).build();
       HttpResponse<String> response = client.send(
               request,
               HttpResponse.BodyHandlers.ofString()
      );
       System.out.println(response.statusCode());
       System.out.println(response.body());
  }

   /**
    * 异步get
    * @param uri
    * @throws Exception
    */
   private static void asyncGet(String uri) throws Exception{
       HttpClient client = HttpClient.newHttpClient();
       HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)).build();
       CompletableFuture<HttpResponse<String>> future =
               client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
       future.whenComplete((resp,ex)  -> {
           if (ex != null) {
               ex.printStackTrace();
          } else {
               System.out.println(resp.statusCode());
               System.out.println(resp.body());
          }
      }).join();


  }
   public static void main(String[] args) throws Exception{
       String uri = "http://t.weather.sojson.com/api/weather/city/101030100";
//       syncGet(uri);
       asyncGet(uri);
  }
}


10分钟了解JDK11新特性


JEP323:Lambda参数的本地变量语法

摘要:允许var在声明隐式类型的lambda表达式的形式参数时使用

目标:将隐式类型的lambda表达式中的形式参数声明的语法和局部变量声明的语法对齐

public class LocalVarExample {

   private static void lambdaInJava8() {
       new Thread(new Runnable(){

           @Override
           public void run() {
               System.out.println("Before java8");
          }
      }).start();

       new Thread(() -> System.out.println("in Java8")).start();
       List<String> list = Arrays.asList("java8","jdk8","1.8");
       list.forEach(w -> {
           System.out.println("lambda in java8");
           System.out.println(w);
      });
  }

   /**
    * <1>Java10新特性:局部变量类型推断</1>
    *
    */
   private static void varInJava10() {
       int var = 10;
       var i = 10;
       var str = "java10";
       var list1 = new ArrayList<String>();
       var map = Map.of(1,"a",2,"b");
       for (var entry : map.entrySet()){
           System.out.println(entry);
      }
  }

   /**
    * <h1>Java11新特性:Lambda表达式可以使用var标志</h1>
    * @param
    */
   private static void lambdaWithVarInJava11() {
       List<Integer> nums = Arrays.asList(8,11,10);
       nums.sort((var s1, var s2) -> {
           if (s1.equals(s2)) {
               return 0;
          } else {
               return s1 > s2 ? 1 : -1;
          }
      });
       System.out.println(nums);
  }

   public static void main(String[] args) {
       lambdaInJava8();
       lambdaWithVarInJava11();
  }
}

JEP327:Unicode 10

摘要:升级现有的平台的API,支持Unicode 10http://unicode.org/versions/Unicode10.0.0/标准。

目标:支持最新版本的Unicode,主要体现在以下类:

  • java.lang中的Character,String

  • java.awt.font中的NumericShaper

  • java.text中的Bidi,BreakIterator,Normalizer

public class Unicode10Example {
   public static void main(String[] args) {
       System.out.println("\uD83E\uDDDA");
       System.out.println("\uD83E\uDDDB");
       System.out.println("\uD83E\uDDDD");
       System.out.println("\uD83E\uDDDE");
       System.out.println("\uD83E\uDDDF");
  }
}

JEP330:启动但文件源代码程序

摘要:增强Java启动程序以运行作为单个Java源代码文件提供的程序

目标:使用java HelloWorld.java运行源代码文件

10分钟了解JDK11新特性


JEP333:可伸缩低延迟垃圾收集器

摘要:Z垃圾收集器,也称为ZGC,是一个可伸缩的低延迟垃圾收集器

目标:(最核心)无论开了多大的堆内存(128G,2T),保证低于10ms的JVM停顿,远胜于前一代的G1

  • 引用计数算法

    • 概念:堆中每个对象都有一个引用计数器,当一个对象被创建并初始化赋值后,该变量计数设置为1,每当一个地方引用它时,计数器值就加1,当引用失效时,计数器就减1,任何引用计数为0的对象可以被当作垃圾收集

    • 优点:引用计数收集器执行简单,判定效率高,交织在程序运行中,堆程序不被长时间打断的实施环境比较有利(OC的内存管理使用该算法)

    • 缺点:难以检测出对象之间的循环引用,同时,引用计数器增加了程序执行的开销,所以Java语言并没有选择这种算法进行垃圾回收

  • 根搜索算法

    • 标记可达对象:JVM中用到的所有现在GC算法在回收前都会先找出所有仍存活的对象,根搜索算法时从离散数学中的图论引入的,程序把所有的引用关系看作一张图。

  • 回收垃圾对象内存的算法

    • Tracing算法(Tracing Collector)或标记--清除算法

    • Compacting算法(Compacting Collector)或标记--整理算法

  • 垃圾收集器

    • Pause Mark Start - 初始停顿标记

    • Concurrent Mark - 并发标记

    • Relocate - 移动对象

    • Remap - 修正指针

    • 所有阶段几乎都是并发执行

    • 像G1一样划分Region,更加灵活

    • 和G1一样会做Compacting-压缩

    • 单代

    • 说明:G1收集器是当今收集器技术发展最前沿的成果,是一款面向服务器端应用的收集器,重复利用多CPU,多核环境。因此它时一款并行和并发收集器,并且它可建立可预测的停顿时间模型

    • 使用:通过JVM参数-XX:+UseG1GC使用G1垃圾回收器

    • 说明:是JVM默认垃圾回收器,使用多线程进行垃圾回收

    • 使用:可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4指定线程数

    • 说明:单线程环境设计,只使用一个单独的线程进行垃圾回收,是client级别默认的GC方式

    • 使用:通过JVM参数 -XX:+UseSerialGC可以使用串型垃圾回收器

    • 串型垃圾收集器(Serial Garbage Collector)

    • 并行垃圾收集器(Parallel Garbage Collector)

    • G1收集器(G1 Garbage Collector)

    • ZGC特性

    • ZGC工作过程


JDK11新API

  • String

    • strip :去掉前后的空格,unicode空格

    • isBlack :字符串为空或者紧包含空格返回true

    • lines:返回字符串提取的流

    • repeat :返回字符串重复次数

    • stripLeading : 去掉前面的空格

    • stripTrailing : 去掉后面的空格

  • Files

    • readString :直接通过路径写文件

    • writeString :直接通过路径读文件

  • List

public class StringExample {

   public static void main(String[] args) {
       String example = "Hello,World!\u3000";
       String empty = "\u3000";
       String line = "hello\nworld\ngerry\n";
       System.out.println("原始example:" + example);
       System.out.println("trim:" + example.trim() + "end");
       System.out.println("strip:" + example.strip() + "end");
       System.out.println("原始empty:" + empty + "end");
       System.out.println("trim:" + empty.trim() + "end");
       System.out.println("strip:" + empty.strip() + "end");
       //isBlack基于unicode识别
       System.out.println("isBlank:" + empty.isBlank());
       System.out.println("isEmpty:" + empty.isEmpty());
       //line
       line.lines().forEach(System.out::println);
       //repeat
       System.out.println("*".repeat(50));
  }
}


10分钟了解JDK11新特性

public class FileExample {
   public static void main(String[] args) throws IOException {
       String path = "/Users/gerrydeng/Desktop/test.txt";
       Files.writeString(Path.of(path),"hello world!hahahhahha", StandardCharsets.UTF_8);
       System.out.println(Files.readString(Path.of(path),StandardCharsets.UTF_8));
  }
}

public class ListExample {

   public static void main(String[] args) {
       //of生成不可变数组
       List<String> list = List.of("gerry","tom","marry");

       System.out.println(list);
       
       String[] oldWay = list.toArray(new String[0]);
       
       String[] newWay = list.toArray(String[]::new);
       
  }
}

JDK11其他特性

  • JEP318:误操作垃圾收集器

  • JEP320:移除JavaEE和CORBA模块

  • JEP324:Curve25519和Curve448算法的密钥协议

  • JEP328:Flight Recorder

  • JEP329:ChaCha20和Poly1305算法

  • JEP331:低开销的Heap Profiling

  • JEP332:支持TLS 1.3

  • JEP335:弃用Nashorn和javascript引擎

  • JEP336:弃用Pack200工具和API

长按识别以下二维码关注我,定期发送资深工程师学习笔记,知识干货,一般网上搜不到哦!码字不容易,转请注出处和二维码。


以上是关于10分钟了解JDK11新特性的主要内容,如果未能解决你的问题,请参考以下文章

JDK 5 ~ 10 新特性倾情整理!

JDK11的新特性你了解了吗?JDK12已经来了!13还远吗?

DK1.5-JDK11各个新特性

jdk11新特性——Unicode 10

jdk11新特性——Unicode 10

Java 10 的 10 个新特性,将彻底改变你写代码的方式!