JDK10新特性

传送门

SpringMVC的源码解析(精品)
Spring6的源码解析(精品)
SpringBoot3框架(精品)
MyBatis框架(精品)
MyBatis-Plus
SpringDataJPA
SpringCloudNetflix
SpringCloudAlibaba(精品)
Shiro
SpringSecurity
java的LOG日志框架
Activiti(敬请期待)
JDK8新特性
JDK9新特性
JDK10新特性
JDK11新特性
JDK12新特性
JDK13新特性
JDK14新特性
JDK15新特性
JDK16新特性
JDK17新特性
JDK18新特性
JDK19新特性
JDK20新特性
JDK21新特性
其他技术文章传送门入口

前言

JDK10提供了超过109项新功能特性,并且JDK10的安装不用再额外安装一次jre了,之前JDK9以及之前都需要额外安装一次jre。

一、局部变量类型推断

1、概念

JDK10 可以使用 var 进行 局部变量类型推断。

1.1、简单局部变量推断

var str = "abc"; // 推断为 字符串类型 
var l = 10L; // 推断为long 类型 
var flag = true; // 推断为 boolean 类型 
var list = new ArrayList<String>(); // 推断为 ArrayList<String> 
var stream = list.stream(); // 推断为 Stream<String> 

1.2、自定义对象的推断

package com.zt.jdk10NewFeatures;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class Jdk10NewFeatures {
    // 局部变量类型推断
    // 1、只针对局部变量
    // 2、var是保留类型不是关键字,意味着我们可以用var来定义变量名
    // 3、var不容许赋值为null,例如  var x = null; 会报错
    public static void main(String[] args) {
        var i = 10;
        System.out.println(i);// 10
        var str = "zt";
        System.out.println(str);// zt
        var list = new ArrayList<>();
        list.add(10);
        list.forEach(System.out::println);// 10
        var set = new HashSet<>();
        set.add(10);
        set.forEach(System.out::println);// 10
        var map = new HashMap<>();
        map.put("JDK10",10);
        map.forEach((k,v) -> {
            System.out.println("key:" + k + ",value:" + v);// key:JDK10,value:10
        });
        var user = new User("zt",18);
        System.out.println(user);// User{username='zt', age=18}
    }

    // 内部类User
    static class User {
        private String username;
        private Integer age;

        public User() {
        }

        public User(String username, Integer age) {
            this.username = username;
            this.age = age;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public Integer getAge() {
            return age;
        }

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

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

2、可以使用的场景

  • 局部变量
  • 循环内
public class demo01var {
    // var x = 10; // 成员变量不能使用var
    public static void main(String[] args) {
        var a = 1;
        var str = "abc";
        var flag = true;
        var list = new ArrayList<String>();
        list.add("aa");
        var stream = list.stream();
        for (var s : list) {
            System.out.println(s);
        }
        for (var i = 0; i < 10; i++) {

            var x = 5;

        }
    }
}

3、不能使用的场景

  • 成员变量
  • 方法参数
  • 方法返回类型
public class demo01var { 

	// var x = 10; // 成员变量不能使用var 

	// 参数不能使用var
	// public static void test01(var a) {}

    /* 方法返回类型不能使用var 
	public static var test02() { 
	return true; 
	}*/
}

4、注意事项

var 并不是一个关键字,可以作为标识符,这意味着可以将一个变量、方法、包名写成 var 。不过一般情况下
不会有人这么写的,因为这本身就违反了普遍的命名规范。

// var 并不是一个关键字,而是一个保留的类型名称,这意味着可以将一个变量、方法、包名写成 `var`。 
public static void test03() {
 	var var = 10; System.out.println("var = " + var); 
}

var 声明变量的时候必须赋值、不能用于声明多个变量的情况。

// var 不能用来声明没有赋值的变量、不能用于声明多个变量的情况。 
public static void test04() { 
	// var x = null; 
	// 不行,推断不出到底是什么类型 
	int x = 1, y = 2; // 可以 
	// var m = 1, n = 2; // 不行 
}

二、垃圾回收器的优化

1、前置知识

1.1、10种垃圾回收器

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.2、分代与分区

在这里插入图片描述

1.3、10种垃圾回收器小总结

  • 1、Serial是串行,现在cpu都多核了,所以一般不用;
  • 2、parNew是多线程,一般用于年轻代,和CMS(老年代)一起搭配使用;
  • 3、CMS只用于老年代收集,它的STW非常短,一般的可达性算法分析,会从gc root 根到末端,它一开始初始标记只标第一段,比如根到引用A,引用A后面其实还有更深更多的引用在第一阶段不去标记,这样会让初始标记的stw非常短,第二阶段再去标记A后面更多更深的引用,但是第二阶段就不用STW了。缺点就是第二阶段剩余标记的时候,实时性没有那么强。第三阶段重新标记,就是重新标记二阶段新产生的对象引用,这阶段也会stw(比第一阶段长一点,这次是完整的根可达性,不过也比第一+第二阶段总时长短很多了),第四阶段就是并发清理,这个不会stw。
    CMS缺点:标记过程中会和用户进程抢资源;无法处理浮动垃圾(第四阶段也会有实时性问题,无法及时清理新产生的);使用的标记清楚算法,会产生大量的内存碎片;会出现CMS一边收集一边回收,没回收完老年代空间不够了触发了新的Full gc,会导致并发模式失败的现象,此时会用其他垃圾回收器了;
  • 4、G1一般用于堆内存10多个G以上的大型公司上,一般公司用的少,年轻代和老年代内存不连续,是堆内存里面一个格子一个格子(见上面G1截图),工作原理和CMS惊人相似,前3阶段标记处理和 CMS一样,4阶段是筛选回收,前3阶段的时候要对每个格子回收时间和成本做计算和排序,4阶段回收的是部分,是成本低的那种先回收了,这个也是G1的王牌标志和牛逼之处。年轻代和老年代都是复制算法。比如E格子和S格子都满了,就会找相近的格子复制有效对象进入形成新的S格子,E格子和S格子就清空了,而且由于格子是一片连续的内存,所以还没有内存碎片问题。而且会发现有多个E格子,所以说一个E格子满了,不会马上年轻代gc,而且会计算设置好的gc时间值,如果小于这个时间,就继续第二个E格子,啥时候E格子满了,gc时间和设置好时间差不多了,就会真正的去年轻代gc。

截图可以看出早期都是配对的。单线程1GB内存以后就效率非常差了。

  • Serial 和Serial Old(单线程的,分代模型);
  • Parallel Scavenge 和 Parallel Old(多线程的,分代模型,jdk8默认的) ;
  • ParNew 和 CMS(前面多线程耗时太多,减少耗时的, ParNew出现也是为了和CMS搭配,分代模型);

上面都是基于分代,分代(年轻代、老年代)的严重缺点还是会随着堆内存增加而stw时间增加;所以后面出了分区模型

  • G1(就是上面格子的那种,一个格子就是一个片区,一块连续的内存空间。标记清除的算法。)
  • ZGC(和其他9种gc不一样,是划时代的gc)
  • Shenandoah
  • Eplison 这个不是真正的去垃圾回收的,只是为了调试用的。

java -XX:+PrintCommandLineFlags -version ---- 查看默认gc,jdk8的默认是 Parallel Scavenge 和 Parallel Old 这一对 , jdk9默认就是g1了

2、优化点

G1 是设计来作为一种低延时的垃圾回收器。G1收集器还可以进行非常精确地对停顿进行控制。从JDK7开始启用G1垃圾回收器,在JDK9中G1成为默认垃圾回收策略。截止到java 9,G1的Full GC采用的是单线程算法。也就是说G1在发生Full GC时会严重影响性能。

JDK10又对G1进行了提升,G1 引入并行 Full GC算法,在发生Full GC时可以使用多个线程进行并行回收。能为用户提供更好的体验。

三、新增API

1、集合新方法copyOf

JDK10 给 java.util 包下的List、Set、Map新增加了一个静态方法 copyOf 。copyof方法将元素放到一个不可修改的集合并返回,是按照之前集合的迭代顺序拷贝的,元素顺序和之前集合一样。

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    List<Integer> temp = List.copyOf(list);
    temp.forEach(System.out::println);// 1  2  3
    temp.add(4);// 不能修改,会报错,如下图        
}

在这里插入图片描述
不可修改这个类似JDK9新特性 集合新增的of方法。

2、ByteArrayOutputStream新增toString方法

JDK10给 java.io.ByteArrayOutputStream 新增重载 toString(Charset charset) 方法,通过指定的字符集编码字节,将缓冲区的内容转换为字符串。

通过ByteArrayOutputStream新增的toString(Charset), 可以将字节数组输出流中的数据按照指定的编码转成字符串。可以更灵活的解决乱码问题。

 String str = "蓝影铁哥";
 ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes("GBK"));
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 int b;
 while ((b = bis.read()) != -1) {
     bos.write(b);
 }
 //默认utf-8
 System.out.println(bos.toString());// ��Ӱ����
 System.out.println(bos.toString("GBK"));// 蓝影铁哥

在这里插入图片描述

3、IO流很多类新增带Charset参数的构造方法

在JDK10中给IO流中的很多类都添加了带Charset参数的方法,比如PrintStream、PrintWriter。通过Charset可以指定编码来操作文本。Charset是一个抽象类,我们不能直接创建对象,需要使用Charset的静态方法forName(“编码”),返回Charset的子类实例。
例如:PrintStream
在这里插入图片描述

// IO流很多类新增带Charset参数的构造方法
public static void main(String[] args) throws Exception {
    String str = "蓝影铁哥";
    var p = new PrintWriter("d:/fe.txt","utf-8");// 将字符串输出到d盘的fe.txt文件中
    p.println(str);
    p.flush();
    p.close();
}

在这里插入图片描述
在这里插入图片描述
这个文本内容的编码就是代码中的utf-8编码,如果代码改成gbk,这文本内容编码也会变成gbk。

4、InputStream和Reader新增transferTo方法

JDK10 给 InputStream 和 Reader 类中新增了 transferTo 方法, transferTo 方法的作用是将输入流读取的数据使用字符输出流写出。可用于复制文件等操作。
例如 Reader:
从这个Reader中读取所有字符串,并按照所读取的顺序将字符串写入给指定的Writer。

// InputStream和Reader新增了transferTo方法
public static void main(String[] args) throws Exception {
    var reader = new BufferedReader(new InputStreamReader(new FileInputStream("d:/fe.txt")));
    var p = new PrintWriter(new File("d:/feNew.txt"));
    reader.transferTo(p);// 从这个Reader中读取所有字符串,并按照所读取的顺序将字符串写入给指定的Writer。
    p.flush();
    p.close();
    reader.close();
}

在这里插入图片描述
在这里插入图片描述

5、Formatter和Scanner新增带Charset参数的构造方法

在JDK10中给java.util.Formatter、java.util.Scanner添加了带Charset参数的构造方法。
例如:Scanner
在这里插入图片描述

 // Formatter和Scanner新增了带Charset参数的构造方法
 public static void main(String[] args) throws Exception {
     var scanner = new Scanner(new FileInputStream(new File("d:/fe.txt")),"utf-8");// 之前写入的一行文字: 蓝影铁哥
     while (scanner.hasNext()){
         System.out.println(scanner.nextLine());// 蓝影铁哥
     }
 }
  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蓝影铁哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值