JDK的前世今生:细数 Java5 - 15 的那些经典特性

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

//获得输出流

OutputStream os = httpExchange.getResponseBody();

os.write(response.toString().getBytes());

os.close();

}

}

4. 插入式注解处理API

JDK 6提供了插入式注解处理API,可以让我们定义的注解在编译期而不是运行期生效,从而可以在编译期修改字节码。lombok框架就是使用该特性来实现的,Lombok通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString等方法,大大简化了代码的开发。

5. STAX

STAX,是JDK6中一种处理XML文档的API。

public class STAXTest {

public static void main(String[] args) throws Exception {

XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();

XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream(“C:\jay.xml”));

XMLEvent event = null;

StringBuffer stringBuffer = new StringBuffer();

while (xmlEventReader.hasNext()) {

event = xmlEventReader.nextEvent();

stringBuffer.append(event.toString());

}

System.out.println(“xml文档解析结果:”);

System.out.println(stringBuffer);

}

}

「运行结果:」

xml文档解析结果:

<?xml version="1.0" encoding='GBK' standalone='yes'?>

ENDDOCUMENT

6. Common Annotations

Common annotations原本是Java EE 5.0(JSR 244)规范的一部分,现在SUN把它的一部分放到了Java SE 6.0中。随着Annotation元数据功能加入到Java SE 5.0里面,很多Java 技术都会用Annotation部分代替XML文件来配置运行参数。

以下列举Common Annotations 1.0里面的几个Annotations:

  • @Generated:用于标注生成的源代码

  • @Resource: 用于标注所依赖的资源,容器据此注入外部资源依赖,有基于字段的注入和基于setter方法的注入两种方式 。

  • @Resources:同时标注多个外部依赖,容器会把所有这些外部依赖注入

  • @PostConstruct:标注当容器注入所有依赖之后运行的方法,用来进行依赖注入后的初始化工作,只有一个方法可以标注为PostConstruct 。

  • @PreDestroy:当对象实例将要被从容器当中删掉之前,要执行的回调方法要标注为PreDestroy

7. Compiler API

javac编译器可以把.java的源文件编译为.class文件,JDK 6的新特性Compiler API(JSR 199)也可以动态编译Java源文件。

public class CompilerApiTest {

public static void main(String[] args) throws Exception {

JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();

StandardJavaFileManager standardJavaFileManager = javaCompiler.getStandardFileManager(null,null,null);

Iterable<? extends JavaFileObject> javaFileObjects = standardJavaFileManager.getJavaFileObjects(“C:\Singer.java”);

javaCompiler.getTask(null, standardJavaFileManager, null, null, null, javaFileObjects).call();

standardJavaFileManager.close();

}

}

运行结果:会在C目录生成Singer.class文件

8. 对脚本语言的支持(如: ruby, groovy, javascript)

JDK6增加了对脚本语言的支持(JSR 223),原理是将脚本语言编译成字节码,这样脚本语言也能享用Java平台的诸多优势,包括可移植性,安全等。JDK6实现包含了一个基于Mozilla Rhino的 脚本语言引擎,因此可以支持javascript,当然JDK也支持ruby等其他语言

public class JavaScriptTest {

public static void main(String[] args) throws Exception {

ScriptEngineManager factory = new ScriptEngineManager();

ScriptEngine engine = factory.getEngineByName(“JavaScript”);

String script;

try {

script = “print(‘Hello’)”;

engine.eval(script);// 执行脚本

}catch (Exception e) {

e.printStackTrace();

}

}

}

//output

Hello

Java 7 新特性

1.switch 支持String字符串类型。

String singer = “jay”;

switch (singer) {

case “jay” :

System.out.println(“周杰伦”);

break;

case “eason” :

System.out.println(“陈奕迅”);

break ;

default :

System.out.println(“其他”);

break ;

}

2.try-with-resources,资源自动关闭

JDK 7 之前:

BufferedReader br = new BufferedReader(new FileReader(“d:七里香.txt”));

try {

return br.readLine();

} finally {

br.close();

}

JDK 7 之后:

/*

  • 声明在try括号中的对象称为资源,在方法执行完毕后会被自动关闭

*/

try (BufferedReader br = new BufferedReader(new FileReader(“d:七里香.txt”)) {

return br.readLine();

}

3. 整数类型如(byte,short,int,long)能够用二进制来表示

//0b或者0B表示二进制

int a = 0b010;

int b = 0B010;

4. 数字常量支持下划线

int a = 11_11;//a的值为1111,下划线不影响实际值,提升可读性

5. 泛型实例化类型自动推断,即”<>”

JDK 7 之前:

Map<String, List> map = new HashMap<String, List>();

JDK 7之后:

//不须声明类型,自动根据前面<>推断其类型

Map<String, List> map = new HashMap<>();

6.一个catch中捕获多个异常类型,用(|)分隔开

JDK 7之前

try{

//do something

} catch (FirstException e) {

logger.error(e);

} catch (SecondException e) {

logger.error(ex);

}

JDk 7之后

try{

//do something

} catch (FirstException | SecondException e) {

logger.error(e);

}

7. 增强的文件系统

Java7 提供了全新的NIO2.0 API,方便文件管理的编码。如,可以在java.nio.file包下使用Path、Paths、Files、WatchService等常用类型。

Path path = Paths.get(“C:\jay\七里香.txt”); //创建Path对象

byte[] bytes= Files.readAllBytes(path); //读取文件

System.out.println(path.getFileName()); //获取当前文件名称

System.out.println(path.toAbsolutePath()); // 获取文件绝对路径

System.out.println(new String(bytes, “utf-8”));

8. Fork/join 框架

Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

Fork/join计算1-1000累加值:

public class ForkJoinPoolTest {

private static final Integer DURATION_VALUE = 100;

static class ForkJoinSubTask extends RecursiveTask{

// 子任务开始计算的值

private Integer startValue;

// 子任务结束计算的值

private Integer endValue;

private ForkJoinSubTask(Integer startValue , Integer endValue) {

this.startValue = startValue;

this.endValue = endValue;

}

@Override

protected Integer compute() {

//小于一定值DURATION,才开始计算

if(endValue - startValue < DURATION_VALUE) {

System.out.println("执行子任务计算:开始值 = " + startValue + ";结束值 = " + endValue);

Integer totalValue = 0;

for (int index = this.startValue; index <= this.endValue; index++) {

totalValue += index;

}

return totalValue;

} else {

// 将任务拆分,拆分成两个任务

ForkJoinSubTask subTask1 = new ForkJoinSubTask(startValue, (startValue + endValue) / 2);

subTask1.fork();

ForkJoinSubTask subTask2 = new ForkJoinSubTask((startValue + endValue) / 2 + 1 , endValue);

subTask2.fork();

return subTask1.join() + subTask2.join();

}

}

}

public static void main(String[] args) throws ExecutionException, InterruptedException {

// Fork/Join框架的线程池

ForkJoinPool pool = new ForkJoinPool();

ForkJoinTask taskFuture = pool.submit(new ForkJoinSubTask(1,1000));

Integer result = taskFuture.get();

System.out.println(“累加结果是:” + result);

}

}

运行结果:

执行子任务计算:开始值 = 189;结束值 = 250

执行子任务计算:开始值 = 251;结束值 = 313

执行子任务计算:开始值 = 314;结束值 = 375

执行子任务计算:开始值 = 376;结束值 = 438

执行子任务计算:开始值 = 439;结束值 = 500

执行子任务计算:开始值 = 501;结束值 = 563

执行子任务计算:开始值 = 564;结束值 = 625

执行子任务计算:开始值 = 626;结束值 = 688

执行子任务计算:开始值 = 689;结束值 = 750

执行子任务计算:开始值 = 751;结束值 = 813

执行子任务计算:开始值 = 814;结束值 = 875

执行子任务计算:开始值 = 876;结束值 = 938

执行子任务计算:开始值 = 939;结束值 = 1000

累加结果是:500500

Java 8 新特性

1.lambada表达式

Lambda 允许把函数作为一个方法的参数,传递到方法中

语法格式:

(parameters) -> expression 或 (parameters) ->{ statements; }

代码示例:

Arrays.asList(“jay”, “Eason”, “SHE”).forEach(

( String singer ) -> System.out.print( singer + “,”) );

2. 函数式接口

Lambda的设计者为了让现有的功能与Lambda表达式很好兼容,设计出函数式接口。

  • 函数式接口是指只有一个函数的接口,可以隐式转换为lambada表达式。

  • Java 8 提供了注解@FunctionalInterface,显示声明一个函数式接口。

  • java.lang.Runnable和java.util.concurrent.Callable是函数式接口的例子~

@FunctionalInterface

public interface Runnable {

public abstract void run();

}

3. 方法引用

方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。它与Lambda表达式配合使用,可以减少冗余代码,使代码更加简洁。

//利用函数式接口Consumer的accept方法实现打印,Lambda表达式如下

Consumer consumer = x -> System.out.println(x);

consumer.accept(“jay”);

//引用PrintStream类(也就是System.out的类型)的println方法,这就是方法引用

consumer = System.out::println;

consumer.accept(“私信资料,领一线大厂面试专题”);

4. 默认方法

默认方法就是一个在接口里面有了一个实现的方法。它允许将新方法添加到接口,但不强制实现了该接口的类必须实现新的方法。

public interface ISingerService {

// 默认方法

default void sing(){

System.out.println(“唱歌”);

}

void writeSong();

}

//JaySingerServiceImpl 不用强制实现ISingerService的默认sing()方法

public class JaySingerServiceImpl implements ISingerService {

@Override

public void writeSong() {

System.out.println(“写了一首七里香”);

}

}

5.Stream API

Stream API,支持对元素流进行函数式操作,它集成在Collections API 中,可以对集合进行批量操作。常用API:

  • filter 筛选

  • map流映射

  • reduce 将流中的元素组合起来

  • collect 返回集合

  • sorted 排序

  • flatMap 流转换

  • limit返回指定流个数

  • distinct去除重复元素

public class Singer {

private String name;

private Integer songNum;

private Integer age;

}

List singerList = new ArrayList();

singerList.add(new Singer(“jay”, 11, 36));

singerList.add(new Singer(“eason”, 8, 31));

singerList.add(new Singer(“JJ”, 6, 29));

List singerNameList = singerList.stream()

.filter(singer -> singer.getAge() > 30) //筛选年龄大于30

.sorted(Comparator.comparing(Singer::getSongNum)) //根据歌曲数量排序

.map(Singer::getName) //提取歌手名字

.collect(Collectors.toList()); //转换为List

6. Optional

Java 8引入Optional类,用来解决NullPointerException。Optional代替if…else解决空指针问题,使代码更加简洁。

if…else 判空

Singer singer = getSingerById(“666”);

if (singer != null) {

String name = singer.getName();

System.out.println(name);

}

Optional的判空

Optional singer = Optional.ofNullable(getSingerById(“666”));

singer.ifPresent(s -> System.out.println(s.getName()));

7. Date Time API

JDK 8之前的日期API处理存在非线程安全、时区处理麻烦等问题。Java 8 在 java.time包下提供了新的日期API,简化了日期的处理~

LocalDate today = LocalDate.now();

int year = today.getYear();

System.out.println(“今年是” + year);

//是否闰年

System.out.println(“今年是不是闰年:” + today.isLeapYear());

LocalDateTime todayTime = LocalDateTime.now();

System.out.println(“当前时间” + todayTime);

//时区指定

System.out.println(“美国时间:” + ZonedDateTime.of(todayTime,ZoneId.of(“America/Los_Angeles”)));

LocalDate specailDate = LocalDate.of(2020, 6, 20);

LocalDate expectDate = specailDate.plus(100, ChronoUnit.DAYS);

System.out.println(“比较特别的一天” + specailDate);

System.out.println(“特殊日期的100天” + expectDate);

8. 重复注解

重复注解,即一个注解可以在一个类、属性或者方法上同时使用多次;用@Repeatable定义重复注解

@Repeatable(ScheduleTimes.class)

public @interface ScheduleTime {

String value();

}

public @interface ScheduleTimes {

ScheduleTime[] value();

}

public class ScheduleTimeTask {

@ScheduleTime(“10”)

@ScheduleTime(“12”)

public void doSomething() { }

}

9. Base64

Java 8把Base64编码的支持加入到官方库中~

String str = “私信资料,领一线大厂面试专题”;

String encoded = Base64.getEncoder().encodeToString(str.getBytes( StandardCharsets.UTF_8));

String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);

10. JVM的新特性

使用元空间Metaspace代替持久代(PermGen space),JVM参数使用-XX:MetaSpaceSize和-XX:MaxMetaspaceSize设置大小。

Java 9 新特性

1. java模块系统

什么是模块化?

一个大型系统,比如一个商城网站,它会包含很多模块的,如:订单模块,用户信息模块,商品信息模块,广告位模块等等。各个模块之间会相互调用。如果每个模块单独运行都会带动其他所有模块,性能非常低效。但是,如果某一模块运行时,只会启动它所依赖的模块,性能大大提升。这就是JDK 9模块化的思想。

什么是JDK 9模块化?

Java 平台模块系统,即Project Jigsaw,把模块化开发实践引入到了Java平台中。在引入了模块系统之后,JDK 被重新组织成94个模块。Java 应用可以通过新增的jlink 工具,创建出只包含所依赖的JDK模块的自定义运行时镜像。这样可以极大的减少Java运行时环境的大小。

Java 9 模块的重要特征:

  • 在其工件(artifact)的根目录中包含了一个描述模块的 module-info.class 文 件。
  • 工件的格式可以是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。
  • 这个文件由根目录中的源代码文件 module-info.java 编译而来。
  • 该模块声明文件可以描述模块的不同特征。

在 module-info.java 文件中,我们可以用新的关键词module来声明一个模块,如下所示。下面给出了一个模块com.mycompany.mymodule的最基本的模块声明

module com.jay.sample { //关键词module来声明一个模块

exports com.jay.sample; //使用 exports可以声明模块对其他模块所导出的包。

requires com.jay.common; //使用requires可以声明模块对其他模块的依赖关系。

}

2. 不可变集合工厂方法

为了创建不可变集合,JDK9之前酱紫的:

List stringList = new ArrayList<>();

stringList.add(“私信资料:”);

stringList.add(“领一线大厂面试专题”);

List unmodifiableList = Collections.unmodifiableList(stringList);

JDK 9 提供了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合:

List unmodifiableList = List.of(“私信资料:”,“领一线大厂面试专题”);

3. 接口支持私有方法

JDK 8支持在接口实现默认方法和静态方法,但是不能在接口中创建私有方法,为了避免了代码冗余和提高阅读性,JDK 9在接口中支持私有方法。

public interface IPrivateInterfaceTest {

//JDK 7 之前

String a = “jay”;

void method7();

//JDK 8

default void methodDefault8(){

System.out.println(“JDK 8新特性默认方法”);

}

static void methodStatic8() {

System.out.println(“JDk 8新特性静态方法”);

}

//Java 9 接口支持私有方法

private void method9(){}

}

4.  钻石操作符升级
  • 钻石操作符是在 java 7 中引入的,可以让代码更易读,但它不能用于匿名的内部类。

  • 在 java 9 中, 它可以与匿名的内部类一起使用,从而提高代码的可读性。

//JDK 5,6

Map<String, String> map56 = new HashMap<String,String>();

//JDk 7,8

Map<String, String> map78 = new HashMap<>();

//JDK 9 结合匿名内部类的实现

Map<String, String> map9 = new HashMap<>(){};

5. Optional 类改进

java 9 中,java.util.Optional 添加了很多新的有用方法,如:

  • stream()

  • ifPresentOrElse()

  • or()

ifPresentOrElse 方法的改进就是有了 else,接受两个参数 Consumer 和 Runnable。

import java.util.Optional;

public class OptionalTest {

public static void main(String[] args) {

Optional optional = Optional.of(1);

optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->

System.out.println(“Not Present.”));

optional = Optional.empty();

optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->

System.out.println(“Not Present.”));

}

}

6. 多版本兼容Jar包

很多公司使用的JDK都是老版本的,JDK6、JDk5 ,甚至JDk4的,不是他们不想升级JDk版本,而是担心兼容性问题。JDK 9的一个新特性,多版本兼容Jar包解决了这个问题。举个例子:假设你一直用的是小米8,已经非常习惯它的运行流程了,突然出来小米9,即使小米9很多新功能引人入胜,但是有些人不会轻易买小米9,因为已经已经习惯小米8的流程。同理,为什么很多公司不升级JDK,就是在此。但是呢,JDK 9的这个功能很强大,它可以让你的版本升级到JDK 9,但是还是老版本的运行流程,即在老的运行流程继承新的功能~

7. JShell工具

jShell工具相当于cmd工具,然后呢,你可以像在cmd工具操作一样,直接在上面运行Java方法,Java语句等~

jshell> System.out.println(“私信资料,领一线大厂面试专题”);

私信资料,领一线大厂面试专题

8. try-with-resources的改进

JDK 9对try-with-resources异常处理机制进行了升级~

//JDK 7,8

try (BufferedReader br = new BufferedReader(new FileReader(“d:七里香.txt”)) {

br.readLine();

}catch(IOException e){

log.error(“IO 异常,e:{}”,e);

}

//JDk 9

BufferedReader br = new BufferedReader(new FileReader(“d:七里香.txt”)

try(br){

br.readLine();

}catch(IOException e){

log.error(“IO 异常,e:{}”,e);

}

9. Stream API的改进

JDK 9 为Stream API引入以下这些方法,丰富了流处理操作:

  • takeWhile()

  • dropWhile()

  • iterate

  • ofNullable

「takeWhile」

使用一个断言(Predicate 接口)作为参数,返回给定Stream的子集直到断言语句第一次返回 false

// 语法格式

default Stream takeWhile(Predicate<? super T> predicate)

//代码示例

Stream.of(1,2,3).takeWhile(s-> x<2)

.forEach(System.out::println);

//输出

1

「dropWhile」

与 takeWhile()作用相反,使用一个断言(Predicate 接口)作为参数,直到断言语句第一次返回true,返回给定Stream的子集

//语法

default Stream dropWhile(Predicate<? super T> predicate)

//代码示例

Stream.of(1,2,3).dropWhile(s-> x<2)

.forEach(System.out::println);

//输出

2

3

「iterate」

iterate() 方法能够返回以seed(第一个参数)开头,匹配 Predicate(第二个参数)直到返回false,并使用第三个参数生成下一个元素的元素流。

//语法

static Stream iterate(T seed, Predicate<? super T> hasNext, UnaryOperator next)

//代码示例

IntStream.iterate(2, x -> x < 10, x -> x*x).forEach(System.out::println);

//输出

2

4

「ofNullable」

如果指定元素为非null,则获取一个元素并生成单个元素流,元素为null则返回一个空Stream。

//语法

static Stream ofNullable(T t)

//代码示例

Stream s1= Stream.ofNullable(100);

s1.forEach(System.out::println)

Stream s2 = Stream.ofNullable(null);

s2.forEach(System.out::println)

//输出

100

10.其他

  • HTTP 2客户端 (支持 WebSocket和 HTTP2 流以及服务器推送)
  • 进程API(控制和管理操作系统进程)
  • String底层存储结构更改(char[]替换为byte[])
  • 标识符添加限制( String _ ="hello"不能用)
  • 响应式流 API (支持Java 9中的响应式编程)

Java 10 新特性

1.局部变量类型推断

JDK 10增加了局部变量类型推断(Local-Variable Type Inference)功能,让 Java 可以像Js里的var一样可以自动推断数据类型。Java中的var是一个保留类型名称,而不是关键字。

JDK 10之前

List list = new ArrayList();

Stream stream = Stream.of(1, 2, 3);

JDK 10 之后

var list = new ArrayList(); // ArrayList

var stream = Stream.of(1, 2, 3);

var 变量类型推断的使用也有局限性,仅**「局限」**于以下场景:

  • 具有初始化器的局部变量

  • 增强型for循环中的索引变量

  • 传统for循环中声明的局部变量

而**「不能用于」**

  • 推断方法的参数类型

  • 构造函数参数类型推断

  • 推断方法返回类型

  • 字段类型推断

  • 捕获表达式

2. 不可变集合的改进

JDK 10中,List,Set,Map 提供了一个新的静态方法copyOf(Collection<? extends E> coll),它返回Collection集合一个不可修改的副本。

JDK 源码:

static List copyOf(Collection<? extends E> coll) {

return ImmutableCollections.listCopy(coll);

}

使用实例:

var oldList = new ArrayList();

oldList.add(“私信资料:”);

oldList.add(“”);

var copyList = List.copyOf(oldList);

oldList.add(“收藏、转载、点赞三连”);

copyList.add(“双击666”); //UnsupportedOperationException异常

3. 并行全垃圾回收器 G1

JDK 9引入 G1 作为默认垃圾收集器,执行GC 时采用的是基于单线程标记扫描压缩算法(mark-sweep-compact)。为了最大限度地减少 Full GC 造成的应用停顿的影响,Java 10 中将为 G1 引入多线程并行 GC,同时会使用与年轻代回收和混合回收相同的并行工作线程数量,从而减少了 Full GC 的发生,以带来更好的性能提升、更大的吞吐量。

4. 线程本地握手

Java 10 中线程管控引入JVM安全点的概念,将允许在不运行全局JVM安全点的情况下实现线程回调,由线程本身或者JVM线程来执行,同时保持线程处于阻塞状态,这将会很方便使得停止单个线程或不停止线程成为可能。

5. Optional新增orElseThrow()方法

Optional、OptionalDouble等类新增一个方法orElseThrow(),在没有值时抛出异常

6. 其他新特性
  • 基于 Java 的 实验性 JIT 编译器

  • 类数据共享

  • Unicode 语言标签扩展

  • 根证书

  • 基于时间(Time-Based)的版本控制模型

Java 11 新特性

1.字符串操作

String类是Java最常用的类,JDK 11增加了一系列好用的字符串处理方法

  • isBlank() 判空。

  • strip() 去除首尾空格

  • stripLeading() 去除字符串首部空格

  • stripTrailing() 去除字符串尾部空格

  • lines() 分割获取字符串流。

  • repeat() 复制字符串

// 判断字符串是否为空白

" ".isBlank(); // true

// 去除首尾空格

" jay ".strip(); // “jay”

// 去除首部空格

" jay ".stripLeading(); // "jay "

去除字符串尾部空格

" jay “.stripLeading(); // " jay”

// 行数统计

“a\nb\nc”.lines().count(); // 3

// 复制字符串

“jay”.repeat(3); // “jayjayjay”

2.用于 Lambda 参数的局部变量语法

局部变量类型推断是Java 10引入的新特性,但是不能在Lambda 表达式中使用。Java 11再次创新,它允许开发者在 Lambda 表达式中使用 var 进行参数声明。

var map = new HashMap<String, Object>();

map.put(“私信资料”, “领一线大厂面试专题”);

map.forEach((var k, var v) -> {

System.out.println(k + ": " + v);

});

3.标准化HTTP Client

Java 9 引入Http Client API,Java 10对它更新,Java 11 对它进行标准化。这几个版本后,Http Client几乎被完全重写,支持HTTP/1.1和HTTP/2 ,也支持 websockets。

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()

.uri(URI.create(“https://github.com/whx123/JavaHome”))

.GET()

.build();

// 同步

HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

// 异步

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())

.thenApply(HttpResponse::body)

.thenAccept(System.out::println);

4. 单个命令编译运行源代码

Java 11增强了Java 启动器,使之能够运行单一文件的Java 源代码。

  • Java 11之前,要运行一个 Java 源代码必须先编译,再运行

// 编译

javac Jay.java

// 运行

java Jay

  • Java 11之后,只要一个java命令就搞定

java Jay.java

5. ZGC:可伸缩低延迟垃圾收集器

ZGC ,即 Z Garbage Collector(垃圾收集器或垃圾回收器)。它是一个可伸缩的、低延迟的垃圾收集器。 ZGC 主要为了满足如下目标进行设计:

  • GC 停顿时间不超过 10ms

  • 既能处理几百 MB 的小堆,也能处理几个 TB 的大堆

  • 应用吞吐能力不会下降超过 15%(与 G1 回收算法相比)

  • 方便在此基础上引入新的 GC 特性和利用 colord

  • 针以及 Load barriers 优化奠定基础

  • 当前只支持 Linux/x64 位平台

6.其他一些特性
  • 添加 Epsilon 垃圾收集器。

  • 支持 TLS 1.3 协议

  • 飞行记录器分析工具

  • 动态类文件常量

  • 低开销的 Heap Profiling

Java 12 新特性

1. Switch 表达式扩展(预览功能)

传统的switch语句,容易漏写break而出错,同时写法并不简洁优雅。

Java 12之前

switch (day) {

case MONDAY:

case FRIDAY:

case SUNDAY:

System.out.println(6);

break;

case TUESDAY:

System.out.println(7);

break;

case THURSDAY:

case SATURDAY:

System.out.println(8);

break;

case WEDNESDAY:

System.out.println(9);

break;

}

JDk 12 之后,Switch表达式得到增强,能接受语句和表达式。

switch (day) {

case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);

case TUESDAY -> System.out.println(7);

case THURSDAY, SATURDAY -> System.out.println(8);

case WEDNESDAY -> System.out.println(9);

}

2. 紧凑的数据格式

JDK 12 新增了NumberFormat对复杂数字的格式化

NumberFormat numberFormat = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT);

System.out.println(numberFormat.format(100000));

//output

10万

3. 字符串支持transform、indent操作
  • transform 字符串转换,可以配合函数式接口Function一起使用

List list1 = List.of(“jay”, " 私信资料,领一线大厂面试专题");

List list2 = new ArrayList<>();

list1.forEach(element ->

list2.add(element.transform(String::strip)

.transform((e) -> “Hello,” + e))

);

list2.forEach(System.out::println);

//输出

Hello,jay

Hello,私信资料,领一线大厂面试专题

  • indent 缩进,每行开头增加空格space和移除空格

String result = “Java\n Python\nC”.indent(3);

System.out.println(result);

//输出

Java

Python

C

4. Files.mismatch(Path, Path)

Java 12 新增了mismatch方法,此方法返回第一个不匹配的位置,如果没有不匹配,则返回 -1L。

public static long mismatch(Path path, Path path2) throws IOException;

代码示例:

Path file1 = Paths.get(“c:\jay.txt”);

Path file2 = Paths.get(“c:\私信资料领一线大厂面试专题.txt”);

try {

long fileMismatch = Files.mismatch(file1, file2);

System.out.println(fileMismatch);

} catch (IOException e) {

e.printStackTrace();

}

5. Teeing Collector

Teeing Collector 是 Streams API 中引入的新的收集器实用程序,它的作用是 merge 两个 collector 的结果,API格式如下:

public static <T, R1, R2, R>

Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,

Collector<? super T, ?, R2> downstream2,

BiFunction<? super R1, ? super R2, R> merger)

直接看代码例子吧,如下为求学生的平均分和总分的例子

List studentList= Arrays.asList(

new Student(“jay”, 90),

new Student(“私信资料,领一线大厂面试专题”, 100),

new Student(“私信资料,领一线大厂面试专题”, 80)

);

String teeingResult=studentList.stream().collect(

Collectors.teeing(

Collectors.averagingInt(Student::getScore),

Collectors.summingInt(Student::getScore),

(s1,s2)-> s1+ “:”+ s2

)

);

System.out.println(teeingResult); //90:270

6.其他特性
  • 支持unicode 11(684个新字符、11个新blocks、7个新脚本)

  • JVM 常量 API (主要在新的java.lang.invoke.constant包中定义了一系列基于值的符号引用类型,能够描述每种可加载常量。)

  • Shenandoah GC(低暂停时间垃圾收集器)

  • G1 收集器提升 (可中止的混合收集集合、及时返回未使用的已分配内存)

  • 默认CDS档案

  • JMH 基准测试

Java 13 新特性

Switch 表达式扩展(引入 yield 关键字)

传统的switch:

private static String getText(int number) {

String result = “”;

switch (number) {

case 1, 2:

result = “one or two”;

break;

case 3:

result = “three”;

break;

case 4, 5, 6:

result = “four or five or six”;

break;

default:

result = “unknown”;

break;

Java 13之后,value break 语句不再被编译,而是用 yield 来进行值返回

private static String getText(int number) {

return switch (number) {

case 1, 2:

yield “one or two”;

case 3:

yield “three”;

case 4, 5, 6:

yield “four or five or six”;

复习的面试资料

这些面试全部出自大厂面试真题和面试合集当中,小编已经为大家整理完毕(PDF版)

  • 第一部分:Java基础-中级-高级

image

  • 第二部分:开源框架(SSM:Spring+SpringMVC+MyBatis)

image

  • 第三部分:性能调优(JVM+MySQL+Tomcat)

image

  • 第四部分:分布式(限流:ZK+Nginx;缓存:Redis+MongoDB+Memcached;通讯:MQ+kafka)

image

  • 第五部分:微服务(SpringBoot+SpringCloud+Dubbo)

image

  • 第六部分:其他:并发编程+设计模式+数据结构与算法+网络

image

进阶学习笔记pdf

  • Java架构进阶之架构筑基篇(Java基础+并发编程+JVM+MySQL+Tomcat+网络+数据结构与算法

image

  • Java架构进阶之开源框架篇(设计模式+Spring+SpringMVC+MyBatis

image

image

image

  • Java架构进阶之分布式架构篇 (限流(ZK/Nginx)+缓存(Redis/MongoDB/Memcached)+通讯(MQ/kafka)

image

image

image

  • Java架构进阶之微服务架构篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)

image

image

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
blocks、7个新脚本)

  • JVM 常量 API (主要在新的java.lang.invoke.constant包中定义了一系列基于值的符号引用类型,能够描述每种可加载常量。)

  • Shenandoah GC(低暂停时间垃圾收集器)

  • G1 收集器提升 (可中止的混合收集集合、及时返回未使用的已分配内存)

  • 默认CDS档案

  • JMH 基准测试

Java 13 新特性

Switch 表达式扩展(引入 yield 关键字)

传统的switch:

private static String getText(int number) {

String result = “”;

switch (number) {

case 1, 2:

result = “one or two”;

break;

case 3:

result = “three”;

break;

case 4, 5, 6:

result = “four or five or six”;

break;

default:

result = “unknown”;

break;

Java 13之后,value break 语句不再被编译,而是用 yield 来进行值返回

private static String getText(int number) {

return switch (number) {

case 1, 2:

yield “one or two”;

case 3:

yield “three”;

case 4, 5, 6:

yield “four or five or six”;

复习的面试资料

这些面试全部出自大厂面试真题和面试合集当中,小编已经为大家整理完毕(PDF版)

  • 第一部分:Java基础-中级-高级

[外链图片转存中…(img-xYAYPGvD-1714697274429)]

  • 第二部分:开源框架(SSM:Spring+SpringMVC+MyBatis)

[外链图片转存中…(img-p4saQb0p-1714697274430)]

  • 第三部分:性能调优(JVM+MySQL+Tomcat)

[外链图片转存中…(img-s3qsTVl8-1714697274430)]

  • 第四部分:分布式(限流:ZK+Nginx;缓存:Redis+MongoDB+Memcached;通讯:MQ+kafka)

[外链图片转存中…(img-0DK2rvxi-1714697274430)]

  • 第五部分:微服务(SpringBoot+SpringCloud+Dubbo)

[外链图片转存中…(img-m0891WnO-1714697274431)]

  • 第六部分:其他:并发编程+设计模式+数据结构与算法+网络

[外链图片转存中…(img-Qr5BUoZa-1714697274431)]

进阶学习笔记pdf

  • Java架构进阶之架构筑基篇(Java基础+并发编程+JVM+MySQL+Tomcat+网络+数据结构与算法

[外链图片转存中…(img-3UqtQ55w-1714697274432)]

  • Java架构进阶之开源框架篇(设计模式+Spring+SpringMVC+MyBatis

[外链图片转存中…(img-JIudFsfd-1714697274432)]

[外链图片转存中…(img-qCMgIxCL-1714697274432)]

[外链图片转存中…(img-ZJuDMJIA-1714697274433)]

  • Java架构进阶之分布式架构篇 (限流(ZK/Nginx)+缓存(Redis/MongoDB/Memcached)+通讯(MQ/kafka)

[外链图片转存中…(img-MVrIa2iM-1714697274433)]

[外链图片转存中…(img-ULOW79kf-1714697274433)]

[外链图片转存中…(img-fLwToa8Q-1714697274433)]

  • Java架构进阶之微服务架构篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)

[外链图片转存中…(img-7iZbBmCp-1714697274433)]

[外链图片转存中…(img-TJVcOKq0-1714697274434)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 27
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值