Java11新特性学习总结

1.jShell

就像一个客户端 目录在
在这里插入图片描述
通过命令打开

在这里插入图片描述

相当于进入了main方法 , 简单使用一下

jshell> var name = "xl";
name ==> "xl"

jshell> name
name ==> "xl"

1.快捷提醒与补全

在这里插入图片描述
按tab键进行提醒和补全

jshell> System.out.print
print(     printf(    println(

jshell> System.out.print

2.help命令

jshell> /help
|  键入 Java 语言表达式, 语句或声明。
|  或者键入以下命令之一:
|  /list [<名称或 id>|-all|-start]
|       列出您键入的源
|  /edit <名称或 id>
|       编辑源条目
|  /drop <名称或 id>
|       删除源条目
|  /save [-all|-history|-start] <文件>
|       将片段源保存到文件
|  /open <file>
|       打开文件作为源输入
|  /vars [<名称或 id>|-all|-start]
|       列出已声明变量及其值
|  /methods [<名称或 id>|-all|-start]
|       列出已声明方法及其签名
|  /types [<名称或 id>|-all|-start]
|       列出类型声明
|  /imports
|       列出导入的项
|  /exit [<integer-expression-snippet>]
|       退出 jshell 工具
|  /env [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>] ...
|       查看或更改评估上下文
|  /reset [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>]...
|       重置 jshell 工具
|  /reload [-restore] [-quiet] [-class-path <路径>] [-module-path <路径>]...
|       重置和重放相关历史记录 -- 当前历史记录或上一个历史记录 (-restore)
|  /history [-all]
|       您键入的内容的历史记录
|  /help [<command>|<subject>]
|       获取有关使用 jshell 工具的信息
|  /set editor|start|feedback|mode|prompt|truncation|format ...
|       设置配置信息
|  /? [<command>|<subject>]
|       获取有关使用 jshell 工具的信息
|  /!
|       重新运行上一个片段 -- 请参阅 /help rerun
|  /<id>
|       按 ID 或 ID 范围重新运行片段 -- 参见 /help rerun
|  /-<n>
|       重新运行以前的第 n 个片段 -- 请参阅 /help rerun
|
|  有关详细信息, 请键入 '/help', 后跟
|  命令或主题的名称。
|  例如 '/help /list''/help intro'。主题:
|
|  intro
|       jshell 工具的简介
|  id
|       片段 ID 以及如何使用它们的说明
|  shortcuts
|       片段和命令输入提示, 信息访问以及
|       自动代码生成的按键说明
|  context
|       /env /reload 和 /reset 的评估上下文选项的说明
|  rerun
|       重新评估以前输入片段的方法的说明

2.局部变量

var 关键字来定义,
var val = "123"; 等同于 String val = "123";
他是根据右边的实际值,去推断左边的值的数据类型

注意:

  • 1.类的属性不允许使用var来定义
  • 2.必须赋予初始值

例子:

jshell> Consumer<String> consumer = (var t) -> System.out.println(t.toUpperCase());
consumer ==> $Lambda$21/0x00000008000b6040@59ec2012

jshell> consumer.accept("dasdFSDFSD")
DASDFSDFSD

3.集合中一些增强的Api

of的使用

在这里插入图片描述
通过of去创建一个list集合

List<String> list = List.of("aa", "bb", "cc", "DD");
System.out.println(list);

运行输出

在这里插入图片描述
但 如果这样做呢?
在这里插入图片描述
就会报这个错误
在这里插入图片描述
我们来测试下 快速把数据变成集合的方法
在这里插入图片描述
发现也会报相同的错误
在这里插入图片描述
asList的源码发现,这个ArrayList他继承了一个抽象的类,并不是java.util.ArrayList

接着,发现里面并没有add方法
在这里插入图片描述
而抽象类里面有add方法
在这里插入图片描述
在这里插入图片描述
来看一下add方法
在这里插入图片描述
直接抛了一个异常
所以,他是一个不可添加的集合

那么我们进of方法看一下源码
在这里插入图片描述
ListN方法源码

static final class ListN<E> extends AbstractImmutableList<E>
            implements Serializable {

        static final List<?> EMPTY_LIST = new ListN<>();

        @Stable
        private final E[] elements;

        @SafeVarargs
        ListN(E... input) {
            // copy and check manually to avoid TOCTOU
            @SuppressWarnings("unchecked")
            E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input
            for (int i = 0; i < input.length; i++) {
                tmp[i] = Objects.requireNonNull(input[i]);
            }
            elements = tmp;
        }

        @Override
        public boolean isEmpty() {
            return size() == 0;
        }

        @Override
        public int size() {
            return elements.length;
        }

        @Override
        public E get(int index) {
            return elements[index];
        }

        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            throw new InvalidObjectException("not serial proxy");
        }

        private Object writeReplace() {
            return new CollSer(CollSer.IMM_LIST, elements);
        }
    }

发现它还是个子类
在这里插入图片描述
发现它的父类中,有add方法
在这里插入图片描述
不过很遗憾,add方法里面也抛了这个异常
在这里插入图片描述
实战场景:
在这里插入图片描述
源码:

    public static LocalDate of(int year, int month, int dayOfMonth) {
        YEAR.checkValidValue(year);
        MONTH_OF_YEAR.checkValidValue(month);
        DAY_OF_MONTH.checkValidValue(dayOfMonth);
        return create(year, month, dayOfMonth);
    }

set也是支持的
在这里插入图片描述
Stream也是支持的
在这里插入图片描述
在这里插入图片描述

4.流的一些增强的Api

1.跟简便的消费流的写法

在这里插入图片描述

2.流中没有数据 和 null

1.流中没有数据

如果这样写,会发生什么呢?
在这里插入图片描述
会发现,他什么都没输出
在这里插入图片描述

2.流中有null

在这里插入图片描述
报错了!
在这里插入图片描述
跟踪源码发现:

在这里插入图片描述
在这里插入图片描述
发现了会造成null的原因。
所以不可以传入null!

那么该这么传进去呢?

在这里插入图片描述
在这里插入图片描述
其实就是进行了一个判断
在这里插入图片描述

3.获取和删除方法

1.获取方法 takeWhile

在这里插入图片描述
在这里插入图片描述
发现他是一次性就停止的,如果1%2 不等于0的话,就取出来,后面的就直接break

那么takeWhile方法就是从流中获取判定器为true的元素,一旦为false就终止。
注意:一旦处理过的流,就不能再继续使用!

2.删除方法 dropWhile

在这里插入图片描述

4.流的迭代

1.无限流

在这里插入图片描述
他会无限的循环 -1,为什么呢?
在这里插入图片描述

2.有限流

在这里插入图片描述
在这里插入图片描述
中间的参数,即是判断,如果符合,就停止迭代

5.字符串的新api

判断字符串是否为空白

System.out.println("".isBlank()); //true

去除首位空格

System.out.println(" csdnCxl ".strip()); //csdnCxl

去除尾部空格

System.out.println(" csdnCxl ".stripTrailing()); // csdnCxl

去除首部空格

 System.out.println(" csdnCxl ".stripLeading()); //csdnCxl

复制字符串

System.out.println("nb".repeat(3)); //nbnbnb

行数统计

System.out.println("a\nb\nc\n".lines().count());//3

整体test
在这里插入图片描述

6.Optional加强

创建一个optional对象
在这里插入图片描述

解决空指针问题

在这里插入图片描述

orElse 如果内部引用为null,则返回参数中的引用

    @Test
    public void test1(){

//orElse 如果内部引用为null,则返回参数中的引用
//        Optional<String> optObj = Optional.ofNullable(null);
//        String s = optObj.orElse("123"); //123
//        String s = optObj.orElse(null); //null

        Optional<String> optObj = Optional.ofNullable("default");
        String s = optObj.orElse(null); 

        System.out.println(s);// default

    }

orElseThrow 如果内部引用为null,则抛出异常
源码:

/**
     * If a value is present, returns the value, otherwise throws
     * {@code NoSuchElementException}.
     *
     * @return the non-{@code null} value described by this {@code Optional}
     * @throws NoSuchElementException if no value is present
     * @since 10
     */
    public T orElseThrow() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

orElseGet 如果为空,通过中继器获取

对比源码即可发现

 /**
     * If a value is present, returns the value, otherwise returns
     * {@code other}.
     *
     * @param other the value to be returned, if no value is present.
     *        May be {@code null}.
     * @return the value, if present, otherwise {@code other}
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }

    /**
     * If a value is present, returns the value, otherwise returns the result
     * produced by the supplying function.
     *
     * @param supplier the supplying function that produces a value to be returned
     * @return the value, if present, otherwise the result produced by the
     *         supplying function
     * @throws NullPointerException if no value is present and the supplying
     *         function is {@code null}
     */
    public T orElseGet(Supplier<? extends T> supplier) {
        return value != null ? value : supplier.get();
    }

两者的相差并不大

7.IO文件的API改进

复制文件 transferTo

    @Test
    public void test1() throws Exception{

        ClassLoader classLoader = this.getClass().getClassLoader();
        InputStream resourceAsStream = classLoader.getResourceAsStream("hello");

        try(var os = new FileOutputStream("myfile")) {
            resourceAsStream.transferTo(os);
        }
        resourceAsStream.close();

    }

在这里插入图片描述

8.Http客户端API

public class HttpApiTest {


    /**
     * 同步请求
     * @throws Exception
     */
    @Test
    public void test1() throws Exception{
        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder(URI.create("www.baidu.com")).build();
        BodyHandler<String> responseBodyHandler = BodyHandlers.ofString(); // res处理器

        HttpResponse<String> send = httpClient.send(request, responseBodyHandler);

        System.out.println(send.body());
    }


    /**
     * 异步
     * @throws Exception
     */
    @Test
    public void test2() throws Exception{
        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder(URI.create("www.baidu.com")).build();
        BodyHandler<String> responseBodyHandler = BodyHandlers.ofString(); // res处理器

        CompletableFuture<HttpResponse<String>> httpResponseCompletableFuture = httpClient.sendAsync(request, responseBodyHandler);

        System.out.println(httpResponseCompletableFuture.get().body());


    }

}

9.更简化的编译运行程序

JEP 330:执行源文件中的第一个类,并且不可以使用别的源文件中的自定义类

之前我们需要javac hello.java java hello
而在java11中,直接使用java hello.java 即可
在这里插入图片描述
在这里插入图片描述
发现成功输出!

10.EpsilonGC垃圾回收器

A NoOp Garbage
JDK上对这个特性的描述是: 开发一个处理内存分配但不实现任何实际内存回收机制的GC, 一旦可用堆内存用完, JVM就会退出.
如果有System.gc()调用, 实际上什么也不会发生(这种场景下和-XX:+DisableExplicitGC效果一样), 因为没有内存回收, 这个实现可能会警告用户尝试强制GC是徒劳.

用法 : -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

class Garbage {
	int n = (int)(Math.random() * 100);
	@Override
	public void finalize() {
		System.out.println(this + " : " + n + " is dying");
	}
}
public class EpsilonTest {
	
	public static void main(String[] args) {
		boolean flag = true;
		List<Garbage> list = new ArrayList<>();
		long count = 0;
		while (flag) {
			list.add(new Garbage());
			if (list.size() == 1000000 && count == 0) {
				list.clear();
				count++;
			}
		}
		System.out.println("程序结束");
	}
}

如果使用选项-XX:+UseEpsilonGC, 程序很快就因为堆空间不足而退出

使用这个选项的原因 :
提供完全被动的GC实现, 具有有限的分配限制和尽可能低的延迟开销,但代价是内存占用和内存吞吐量.
众所周知, java实现可广泛选择高度可配置的GC实现. 各种可用的收集器最终满足不同的需求, 即使它们的可配置性使它们的功能相交. 有时更容易维护单独的实现, 而不是在现有GC实现上堆积另一个配置选项.

主要用途如下 :
性能测试(它可以帮助过滤掉GC引起的性能假象)
内存压力测试(例如,知道测试用例 应该分配不超过1GB的内存, 我们可以使用-Xmx1g –XX:+UseEpsilonGC, 如果程序有问题, 则程序会崩溃)
非常短的JOB任务(对象这种任务, 接受GC清理堆那都是浪费空间)
VM接口测试
Last-drop 延迟&吞吐改进

11.ZGC

ZGC, 这应该是JDK11最为瞩目的特性, 没有之一. 但是后面带了Experimental, 说明这还不建议用到生产环境.
ZGC, A Scalable Low-Latency Garbage Collector(Experimental)
ZGC, 这应该是JDK11最为瞩目的特性, 没有之一. 但是后面带了Experimental, 说明这还不建议用到生产环境.
GC暂停时间不会超过10ms
既能处理几百兆的小堆, 也能处理几个T的大堆(OMG)
和G1相比, 应用吞吐能力不会下降超过15%
为未来的GC功能和利用colord指针以及Load barriers优化奠定基础
初始只支持64位系统

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

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

STW – stop the world

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

ZGC : avg 1.091ms max:1.681
G1 : avg 156.806 max:543.846

用法 : -XX:+UnlockExperimentalVMOptions –XX:+UseZGC, 因为ZGC还处于实验阶段, 所以需要通过JVM参数来解锁这个特性

12.完全支持Linux容器(包括Docker)

许多运行在Java虚拟机中的应用程序(包括Apache Spark和Kafka等数据服务以及传统的企业应用程序)都可以在Docker容器中运行。但是在Docker容器中运行Java应用程序一直存在一个问题,那就是在容器中运行JVM程序在设置内存大小和CPU使用率后,会导致应用程序的性能下降。这是因为Java应用程序没有意识到它正在容器中运行。随着Java 10的发布,这个问题总算得以解决,JVM现在可以识别由容器控制组(cgroups)设置的约束。可以在容器中使用内存和CPU约束来直接管理Java应用程序,其中包括:

遵守容器中设置的内存限制
在容器中设置可用的CPU
在容器中设置CPU约束
Java 10的这个改进在Docker for Mac、Docker for Windows以及Docker Enterprise Edition等环境均有效。

容器的内存限制
在Java 9之前,JVM无法识别容器使用标志设置的内存限制和CPU限制。而在Java 10中,内存限制会自动被识别并强制执行。

Java将服务器类机定义为具有2个CPU和2GB内存,以及默认堆大小为物理内存的1/4。例如,Docker企业版安装设置为2GB内存和4个CPU的环境,我们可以比较在这个Docker容器上运行Java 8和Java 10的区别。

首先,对于Java 8:

docker container run -it -m512 --entrypoint bash openjdk:latest
$ docker-java-home/bin/java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
uintx MaxHeapSize                              := 524288000                          {product}
openjdk version "1.8.0_162"

最大堆大小为512M或Docker EE安装设置的2GB的1/4,而不是容器上设置的512M限制。

相比之下,在Java 10上运行相同的命令表明,容器中设置的内存限制与预期的128M非常接近:

docker container run -it -m512M --entrypoint bash openjdk:10-jdk
$ docker-java-home/bin/java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
size_t MaxHeapSize                              = 134217728                          {product} {ergonomic}
openjdk version "10" 2018-03-20

设置可用的CPU
默认情况下,每个容器对主机CPU周期的访问是无限的。可以设置各种约束来限制给定容器对主机CPU周期的访问。Java 10可以识别这些限制:

docker container run -it --cpus 2 openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 2

分配给Docker EE的所有CPU会获得相同比例的CPU周期。这个比例可以通过修改容器的CPU share权重来调整,而CPU share权重与其它所有运行在容器中的权重相关。此比例仅适用于正在运行的CPU密集型的进程。当某个容器中的任务空闲时,其他容器可以使用余下的CPU时间。实际的CPU时间的数量取决于系统上运行的容器的数量。这些可以在Java 10中设置:

docker container run -it --cpu-shares 2048 openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 2

cpuset约束设置了哪些CPU允许在Java 10中执行。

docker run -it --cpuset-cpus="1,2,3" openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 3

分配内存和CPU
使用Java 10,可以使用容器设置来估算部署应用程序所需的内存和CPU的分配。我们假设已经确定了容器中运行的每个进程的内存堆和CPU需求,并设置了JAVA_OPTS配置。例如,如果有一个跨10个节点分布的应用程序,其中五个节点每个需要512Mb的内存和1024个CPU-shares,另外五个节点每个需要256Mb和512个CPU-shares。

请注意,1个CPU share比例由1024表示。

对于内存,应用程序至少需要分配5Gb。

512Mb × 5 = 2.56Gb
256Mb × 5 = 1.28Gb
该应用程序需要8个CPU才能高效运行。

1024 x 5 = 5个CPU
512 x 5 = 3个CPU
最佳实践是建议分析应用程序以确定运行在JVM中的每个进程实际需要多少内存和分配多少CPU。但是,Java 10消除了这种猜测,可以通过调整容器大小以防止Java应用程序出现内存不足的错误以及分配足够的CPU来处理工作负载。

13.支持G1上的并行完全垃圾收集。

对于 G1 GC,相比于 JDK 8,升级到 JDK 11 即可免费享受到:并行的 Full GC,快速的 CardTable 扫描,自适应的堆占用比例调整(IHOP),在并发标记阶段的类型卸载等等。这些都是针对 G1 的不断增强,其中串行 Full GC 等甚至是曾经被广泛诟病的短板,你会发现 GC 配置和调优在 JDK11 中越来越方便。

14.JEP 331 : Low-Overhead Heap Profiling免费的低耗能飞行记录仪和堆分析仪。

通过JVMTI的SampledObjectAlloc回调提供了一个开销低的heap分析方式

提供一个低开销的, 为了排错java应用问题, 以及JVM问题的数据收集框架, 希望达到的目标如下 :
提供用于生产和消费数据作为事件的API
提供缓存机制和二进制数据格式
允许事件配置和事件过滤
提供OS,JVM和JDK库的事件

15.JEP 329 : 实现RFC7539中指定的ChaCha20和Poly1305两种加密算法, 代替RC4

实现 RFC 7539的ChaCha20 and ChaCha20-Poly1305加密算法

RFC7748定义的秘钥协商方案更高效, 更安全. JDK增加两个新的接口

XECPublicKey 和 XECPrivateKey
KeyPairGenerator kpg = KeyPairGenerator.getInstance(“XDH”);
NamedParameterSpec paramSpec = new NamedParameterSpec(“X25519”);
kpg.initialize(paramSpec);
KeyPair kp = kgp.generateKeyPair();

KeyFactory kf = KeyFactory.getInstance(“XDH”);
BigInteger u = new BigInteger(“xxx”);
XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);
PublicKey pubKey = kf.generatePublic(pubSpec);

KeyAgreement ka = KeyAgreement.getInstance(“XDH”);
ka.init(kp.getPrivate());
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret()

16.Java Flight Recorder

Flight Recorder源自飞机的黑盒子

Flight Recorder以前是商业版的特性,在java11当中开源出来,它可以导出事件到文件中,之后可以用Java Mission Control来分析。可以在应用启动时配置java -XX:StartFlightRecording,或者在应用启动之后,使用jcmd来录制,比如
$ jcmd JFR.start
$ jcmd JFR.dump filename=recording.jfr
$ jcmd JFR.stop

是 Oracle 刚刚开源的强大特性。我们知道在生产系统进行不同角度的 Profiling,有各种工具、框架,但是能力范围、可靠性、开销等,大都差强人意,要么能力不全面,要么开销太大,甚至不可靠可能导致 Java 应用进程宕机。
而 JFR 是一套集成进入 JDK、JVM 内部的事件机制框架,通过良好架构和设计的框架,硬件层面的极致优化,生产环境的广泛验证,它可以做到极致的可靠和低开销。在 SPECjbb2015 等基准测试中,JFR 的性能开销最大不超过 1%,所以,工程师可以基本没有心理负担地在大规模分布式的生产系统使用,这意味着,我们既可以随时主动开启 JFR 进行特定诊断,也可以让系统长期运行 JFR,用以在复杂环境中进行“After-the-fact”分析。还需要苦恼重现随机问题吗?JFR 让问题简化了很多。
在保证低开销的基础上,JFR 提供的能力也令人眼前一亮,例如:我们无需 BCI 就可以进行 Object Allocation Profiling,终于不用担心 BTrace 之类把进程搞挂了。对锁竞争、阻塞、延迟,JVM GC、SafePoint 等领域,进行非常细粒度分析。甚至深入 JIT Compiler 内部,全面把握热点方法、内联、逆优化等等。JFR 提供了标准的 Java、C++ 等扩展 API,可以与各种层面的应用进行定制、集成,为复杂的企业应用栈或者复杂的分布式应用,提供 All-in-One 解决方案。而这一切都是内建在 JDK 和 JVM 内部的,并不需要额外的依赖,开箱即用。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java JDK 11Java开发工具包的一个版本,是由Oracle公司研发和发布的。JDK(Java Development Kit)是一个用于开发和编译Java程序的软件包,它提供了Java语言的开发环境和一系列的工具。JDK 11Java的最新版本,于2018年9月发布。 JDK 11带来了许多新的特性和改进。其中一项重要的改变是,JDK 11中引入了模块化系统,即Java平台模块系统(JPMS)。该系统可以帮助开发者更好地管理和组织Java代码和依赖项。另一个重要的改进是JVM性能的提升,包括更快的启动时间和更低的内存占用。 除了这些改进,JDK 11还包含了一些新的API和功能,如HTTP Client API、新的垃圾收集器(ZGC)和低延迟的垃圾收集器(Shenandoah GC),以及对Unicode 10.0的支持。 CSDN是一个知名的IT技术社区和博客网站。它为开发者提供了大量的技术文章、博客、教程等资源。在CSDN上,你可以找到关于Java JDK 11的各种教程、问题解答、开发经验分享等内容。同时,CSDN还提供了很多其他与Java开发相关的资源,如Java框架、库、工具等的介绍和下载链接。 总结来说,Java JDK 11Java开发工具包的一个版本,它带来了许多新的特性和改进。而CSDN是一个IT技术社区和博客网站,为开发者提供了很多与Java开发相关的资源。通过CSDN,你可以获取到关于Java JDK 11的各种教程和知识。 ### 回答2: Java JDK 11Java开发工具包的最新版本,JDK是Java Development Kit的缩写,是开发Java应用程序所需的软件包。JDK 11具有许多新功能和改进,为Java开发者提供更好的工具和性能。 其中一个重要的新功能是模块系统的引入。模块系统允许开发者将代码划分为独立的模块,以提高代码的可重用性和维护性。这种模块化方法有助于构建更可靠和安全的应用程序。 此外,JDK 11还引入了新的语言特性和API。其中包括Lambda表达式的增强、局部变量类型推断和字符串API的改进。这些特性使得Java编程更加简洁和高效。 JDK 11还包含了Java Flight Recorder(JFR)的开源版本。JFR是一种强大的性能分析工具,可以实时监测和记录Java应用程序的性能指标。这使得开发者可以更好地识别和解决性能问题。 此外,JDK 11还具有增强的安全性和可扩展性。它支持TLS 1.3,这是一种更安全的网络协议。此外,JDK 11还提供了更好的内存管理和垃圾回收机制。 CSDN是中国最大的IT社区和技术交流平台。许多Java开发者在CSDN上分享他们的经验和知识。在CSDN上,你可以找到大量关于Java JDK 11的文章和教程,以帮助你学习和掌握JDK 11的新功能和用法。 总结来说,Java JDK 11是一个强大而且功能丰富的开发工具包,它提供了许多新功能和改进,使得Java的开发更加简便和高效。CSDN是一个优秀的资源平台,可以帮助开发者更好地学习和应用JDK 11

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

coder阿龙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值