JDK10新特性

目录

  • 传送门
  • 一、局部变量类型推断
    • 1、概念
      • 1.1、简单局部变量推断
      • 1.2、自定义对象的推断
    • 2、可以使用的场景
    • 3、不能使用的场景
    • 4、注意事项
  • 二、垃圾回收器的优化
    • 1、前置知识
      • 1.1、10种垃圾回收器
      • 1.2、分代与分区
      • 1.3、10种垃圾回收器小总结
    • 2、优化点
  • 三、新增API
    • 1、集合新方法copyOf
    • 2、ByteArrayOutputStream新增toString方法
    • 3、IO流很多类新增带Charset参数的构造方法
    • 4、InputStream和Reader新增transferTo方法
    • 5、Formatter和Scanner新增带Charset参数的构造方法

传送门

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());// 蓝影铁哥
     }
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/208005.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多线程(初阶六:单例模式)

一、单例模式的简单介绍 二、饿汉模式 三、懒汉模式 四、饿汉模式和懒汉模式的线程安全问题分析 一、单例模式的简单介绍 单例模式是一种设计模式&#xff0c;其中设计模式是软性的规定&#xff0c;与它关联的框架是硬性的规定&#xff0c;这些都是大佬已经设计好了的&…

【工作记录】spider-flow使用插件连接并操作mongodb数据库

前言 前面说过&#xff0c;spider-flow有着非常优秀的插件机制&#xff0c;可以通过插件实现功能的扩展。前面有小伙伴问到mongodb的集成使用&#xff0c;本文就来梳理下spider-flow中使用mongodb插件的过程&#xff0c;其实非常简单。 PS: spider-flow的作者已经实现了一些常…

线程池技术总结

1. 线程池解决了什么问题 线程池是集中管理线程的&#xff0c;以实现线程的重用&#xff0c;降低资源消耗&#xff0c;提高响应速度&#xff0c;提高线程的可管理性等。线程用于执行异步任务&#xff0c;单个的线程既是工作单元也是执行机制&#xff0c;从JDK1.5开始&#xff…

文心一言 VS 讯飞星火 VS chatgpt (147)-- 算法导论12.2 2题

二、用go语言&#xff0c;写出 TREE-MINIMUM 和 TREE-MAXIMUM 的递归版本。 灵捷3.5 。 文心一言&#xff1a; 以下是用 Go 语言编写的树的最大值和最小值的递归版本代码&#xff1a; package main import ( "fmt" ) type TreeNode struct { Val int Le…

哈希表 LeetCode 2661. 找出叠涂元素

2661. 找出叠涂元素 给你一个下标从 0 开始的整数数组 arr 和一个 m x n 的整数 矩阵 mat 。arr 和 mat 都包含范围 [1&#xff0c;m * n] 内的 所有 整数。 从下标 0 开始遍历 arr 中的每个下标 i &#xff0c;并将包含整数 arr[i] 的 mat 单元格涂色。 请你找出 arr 中在 …

LeetCode105.从前序和中序遍历序列构造二叉树

这道题看完题想了几分钟就想到大概的思路了&#xff0c;但是在写的时候有很多细节没注意出了很多问题&#xff0c;然后写了1个多小时&#xff0c;其实这道题挺简单的。 首先&#xff0c;最基本的知识&#xff0c;先序遍历是根左右&#xff0c;中序遍历是左根右&#xff0c;那么…

重磅!GPT-4 API,全面开放使用!

7月7日&#xff0c;OpenAI在官网宣布&#xff0c;GPT-4 API全面开放使用。现所有付费API用户都可直接访问8K上下文的GPT-4&#xff0c;无需任何等待。 预计到7月底之前&#xff0c;OpenAI会向全新的开发人员开放GPT-4 API使用权限。&#xff08;API详细使用说明地址&#xff1…

【AB平台数据建设】从实验平台到数据管道

文章目录 前言1.从AB实验平台聊起(1)AB平台在业务中的发挥那些作用(2)AB平台进行实验工作流介绍 2.实验平台底层数据管道最小MVP解构(1)数据管道数据从哪里来&#xff1f;(2)数据管道的输出数据有哪些&#xff1f; 小结 前言 AB实验平台是一种通过小范围放量&#xff0c;测试不…

安装两个WIN10/WIN11系统到两个盘中,第二个系统依赖原系统盘引导的问题

前段时间折腾装一个双系统&#xff0c;主要两个方面考虑&#xff1a; 1. 原来的系统又许多软件&#xff0c;想着先保留&#xff1b; 2. 系统想安装到一个固态硬盘中&#xff1b; 在安装的过程中遇到了一些问题&#xff0c;这里记录分享一下。 问题1&#xff0c;运行系统自动安装…

深入 C 语言和程序运行原理 实战项目代码在CentOS 7上编译

cat /etc/redhat-release看到操作系统的版本是CentOS Linux release 7.6.1810 (Core)&#xff0c;uname -r可以看到内核版本是3.10.0-957.21.3.el7.x86_64。 安装gtest 参考博客《使用gtest和lcov测试代码覆盖率》 wget https://github.com/google/googletest/archive/refs/…

Android NDK项目创建的时候C++版本选择都有什么区别

Android ndk项目在创建的时候有C版本选择有4个选项&#xff0c;分别是Toolchain default&#xff0c; C11&#xff0c;C14&#xff0c;C17。 C是一种广泛使用的编程语言&#xff0c;它不断地发展和更新&#xff0c;以适应不同的需求和场景。C的语言标准是由国际标准化组织&…

2.qml 3D-View3D类学习

本章我们来学习View3D类。 View3D是用来渲染3D场景并显示在2D平面的类&#xff0c;并且该类可以放在QML2D下继承于Item子类的任何场景中&#xff0c;比如将View3D放在Rectangle中: Rectangle {width: 200 height: 200color: "red"View3D { anchors.fill: parent…

九章量子计算机:引领量子计算的新篇章

九章量子计算机:引领量子计算的新篇章 一、引言 随着科技的飞速发展,量子计算已成为全球科研领域的前沿议题。九章量子计算机作为中国自主研发的量子计算机,具有划时代的意义。本文将深入探讨九章量子计算机的原理、技术特点、应用前景等方面,带领读者领略量子计算的魅力…

什么是OV SSL证书?

OV SSL证书是组织验证SSL证书的缩写&#xff0c;是三个SSL验证级别之一的名称。 OV是指实名类型的SSL证书&#xff0c;这个实名其实只要证明发布者身份就可以签发&#xff0c;无论是个人还是企业都可以进行申请。 SSL证书大家都知道就是用于网站地址的http改成https加密协议的…

gromacs学习及使用(1)

1.Gromacs的使用 2.Gromacs 的第一步_能量最小化 3.分子动力学模拟Gromacs一般使用步骤&#xff08;空蛋白&#xff09; 4.GROMACS优化(没看懂) 5.GROMACS快速入门&#xff08;有好东西&#xff09; GROMACS中文教程 gmx editconf -f xxx -o xxx6.GROMACS运行参数之em.mdp文…

Burp Suite序列之目录扫描

如果你是一名渗透测试爱好者或者专业人士&#xff0c;你一定知道目录扫描是渗透测试中非常重要的一步。通过目录扫描&#xff0c;我们可以发现网站的敏感信息&#xff0c;隐藏的功能&#xff0c;甚至是后台入口。目录扫描可以帮助我们更好地了解目标网站的结构和漏洞。 但是&a…

四大视角看EMC设计:滤波、接地、屏蔽、PCB布局

电磁干扰的主要方式是传导干扰、辐射干扰、共阻抗耦合和感应耦合。对这几种途径产生的干扰我们应采用的相应对策&#xff1a;传导采取滤波&#xff0c;辐射干扰采用屏蔽和接地等措施&#xff0c;就能够大大提高产品的抵抗电磁干扰的能力&#xff0c;也可以有效的降低对外界的电…

Shell循环:for(三)

示例&#xff1a;使用for实现批量主机root密码的修改 一、前提 已完成密钥登录配置&#xff08;ssh-keygen&#xff09;定义主机地址列表并了解远程修改密码的方法 [rootlocalhost ~]# ssh-keygen #设置免密登录[rootlocalhost ~]# ssh-copy-id 192.168.151.151 二、演示…

【趣味JavaScript】一文让你读懂JavaScript原型对象与原型链的继承,探秘属性的查找机制! 《重置版》

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

【Linux】第二十三站:缓冲区

文章目录 一、一些奇怪的现象二、用户级缓冲区三、用户级缓冲区刷新问题四、一些其他问题1.缓冲区刷新的时机2.为什么要有这个缓冲区3.这个缓冲区在哪里&#xff1f;4.这个FILE对象属于用户呢&#xff1f;还是操作系统呢&#xff1f;这个缓冲区&#xff0c;是不是用户级的缓冲区…