<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[read and sleep]]></title><description><![CDATA[read and sleep]]></description><link>https://sleep.renxinblog.cn</link><generator>RSS for Node</generator><lastBuildDate>Thu, 14 May 2026 07:00:39 GMT</lastBuildDate><atom:link href="https://sleep.renxinblog.cn/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Jdk21新特性]]></title><description><![CDATA[笔者在过去主要使用的JDK版本是JDK8，最近在学习最新的JDK长期支持版本——JDK21，本文将简要记录一下JDK21相比于JDK8的一些新特性，对于一些比较有意思的新特性也会在后续文章中逐步展开研究。
var关键字局部变量推断
// 仅限局部变量适用 
var name = "renxin";
var age = 18; 
var isMan = true; 
var list = new ArrayList<String>(); 
var map = new HashMap<String,...]]></description><link>https://sleep.renxinblog.cn/jdk21</link><guid isPermaLink="true">https://sleep.renxinblog.cn/jdk21</guid><category><![CDATA[Java]]></category><dc:creator><![CDATA[ren xin]]></dc:creator><pubDate>Thu, 08 May 2025 06:02:56 GMT</pubDate><content:encoded><![CDATA[<p>笔者在过去主要使用的JDK版本是JDK8，最近在学习最新的JDK长期支持版本——JDK21，本文将简要记录一下JDK21相比于JDK8的一些新特性，对于一些比较有意思的新特性也会在后续文章中逐步展开研究。</p>
<h4 id="heading-var">var关键字局部变量推断</h4>
<pre><code class="lang-java"><span class="hljs-comment">// 仅限局部变量适用 </span>
<span class="hljs-keyword">var</span> name = <span class="hljs-string">"renxin"</span>;
<span class="hljs-keyword">var</span> age = <span class="hljs-number">18</span>; 
<span class="hljs-keyword">var</span> isMan = <span class="hljs-keyword">true</span>; 
<span class="hljs-keyword">var</span> list = <span class="hljs-keyword">new</span> ArrayList&lt;String&gt;(); 
<span class="hljs-keyword">var</span> map = <span class="hljs-keyword">new</span> HashMap&lt;String, String&gt;();
</code></pre>
<h4 id="heading-switch">switch 表达式增强</h4>
<pre><code class="lang-java"><span class="hljs-comment">// 假设有枚举定义为</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">Direction</span> </span>{

    EAST,
    SOUTH,
    WEST,
    NORTH,
    NORTHWEST,
    ;
}

<span class="hljs-comment">// switch 表达式为变量赋值</span>
<span class="hljs-keyword">var</span> witchCity = <span class="hljs-keyword">switch</span> (direction) {
    <span class="hljs-keyword">case</span> EAST, NORTHWEST -&gt; <span class="hljs-string">"成都"</span>;
    <span class="hljs-keyword">case</span> WEST -&gt; <span class="hljs-string">"上海"</span>;
    <span class="hljs-keyword">case</span> SOUTH -&gt; <span class="hljs-string">"广州"</span>;
    <span class="hljs-keyword">case</span> NORTH -&gt; <span class="hljs-string">"北京"</span>;
    <span class="hljs-keyword">default</span> -&gt; <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"Invalid direction: "</span> + direction);
};
<span class="hljs-comment">// yield 关键字返回值，并跳出switch表达式（相当于break）</span>
<span class="hljs-keyword">var</span> witchCity = <span class="hljs-keyword">switch</span> (direction) {
    <span class="hljs-keyword">case</span> EAST, NORTHWEST:
        System.out.println(<span class="hljs-string">"成都"</span>);
        yield <span class="hljs-string">"成都"</span>;
    <span class="hljs-keyword">case</span> WEST:
        System.out.println(<span class="hljs-string">"上海"</span>);
        yield <span class="hljs-string">"上海"</span>;
    <span class="hljs-keyword">case</span> SOUTH:
        System.out.println(<span class="hljs-string">"广州"</span>);
        yield <span class="hljs-string">"广州"</span>;
    <span class="hljs-keyword">case</span> NORTH:
        System.out.println(<span class="hljs-string">"北京"</span>);
        yield <span class="hljs-string">"北京"</span>;
    <span class="hljs-keyword">default</span>:
        system.out.println(<span class="hljs-string">"未知"</span>);
        yield <span class="hljs-string">"未知"</span>;
};
<span class="hljs-comment">// yield 关键字结合lambda表达式</span>
<span class="hljs-keyword">var</span> witchCity = <span class="hljs-keyword">switch</span> (direction) {
    <span class="hljs-keyword">case</span> EAST, NORTHWEST -&gt; {
        System.out.println(<span class="hljs-string">"成都"</span>);
        yield <span class="hljs-string">"成都"</span>;
    }
    <span class="hljs-keyword">case</span> WEST -&gt; {
        System.out.println(<span class="hljs-string">"上海"</span>);
        yield <span class="hljs-string">"上海"</span>;
    }
    <span class="hljs-keyword">case</span> SOUTH -&gt; {
        System.out.println(<span class="hljs-string">"广州"</span>);
        yield <span class="hljs-string">"广州"</span>;
    }
    <span class="hljs-keyword">case</span> NORTH -&gt; {
        System.out.println(<span class="hljs-string">"北京"</span>);
        yield <span class="hljs-string">"北京"</span>;
    }
    <span class="hljs-keyword">default</span> -&gt; {
        System.out.println(<span class="hljs-string">"未知"</span>);
        yield <span class="hljs-string">"未知"</span>;
    }
};
</code></pre>
<h4 id="heading-record-class">记录类（record class)</h4>
<pre><code class="lang-java"><span class="hljs-comment">// 定义一个记录类,标注了record关键字，同时指定了name和age两个字段，编译器已经自动为其生成了构造函数、字段访问方法name()和age()。</span>
<span class="hljs-comment">// 除字段不能被修改、不能继承其他类、不能添加实例字段之外其他的特性与普通类相同。</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> record <span class="hljs-title">Student</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
    <span class="hljs-comment">// 不能添加实例字段</span>
    <span class="hljs-comment">// private String teacher;</span>

    <span class="hljs-comment">// 构造器可以自定义</span>
    <span class="hljs-keyword">public</span> Student {
        <span class="hljs-keyword">if</span> (age &lt; <span class="hljs-number">0</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"年龄不能小于0"</span>);
        }
        <span class="hljs-keyword">if</span> (name == <span class="hljs-keyword">null</span> || name.isEmpty()) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">"姓名不能为空"</span>);
        }
    }
    <span class="hljs-comment">// 可以定义方法</span>

    <span class="hljs-comment">// 可以实现接口</span>
}
</code></pre>
<h4 id="heading-sealed-classes">密封类（Sealed Classes）</h4>
<p>密封类的使用场景是定义一个类的继承规则，只有指定的类可以继承该类，其他类不能继承该类。类之间耦合更紧了，但是也提升了类型安全。在编写三方库提供给别人用又不希望被使用者随意继承使用时这个特性会特别有用。</p>
<pre><code class="lang-java"><span class="hljs-comment">// sealed关键字定义一个密封类，同时permits关键字指定了可以继承该类的类</span>
<span class="hljs-keyword">public</span> sealed <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Job</span> <span class="hljs-title">permits</span> <span class="hljs-title">Author</span>, <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">name</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"renxin"</span>;
    }
}

<span class="hljs-comment">// 定义一个final类为密封类的子类，该类不能被继承</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Author</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Job</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">name</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"renxin"</span>;
    }
}

<span class="hljs-comment">// 定义一个non-sealed修饰的类为密封类的子类，该类可以被继承</span>
<span class="hljs-keyword">public</span> non-sealed <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Author</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Job</span> </span>{
}
</code></pre>
<p>使用密封类有以下三个限制：</p>
<ul>
<li>子类必须与密封类处于同一个模块（或同一个包，如果没有模块系统）</li>
</ul>
<ul>
<li>子类必须显式继承密封类，否则编译不通过</li>
</ul>
<ul>
<li>密封类的子类必须被显式声明为final、sealed或non-sealed。</li>
</ul>
<p>这是密封类设计的核心原则。这样做有两方面的好处。明确类的继承结构，防止继承链失控</p>
<p>与模式匹配结合可以在编译期做到穷举检查。Author类、Teacher被明确定义为final修饰的封闭类的子类，编译期可以知道该封闭类被哪些子类继承，做到穷举检查。</p>
<pre><code class="lang-java">  <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> sealed <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Job</span> <span class="hljs-title">permits</span> <span class="hljs-title">Author</span>, <span class="hljs-title">Teacher</span> </span>{}
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Author</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Job</span> </span>{}
  <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Teacher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Job</span> </span>{}

  <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">handle</span><span class="hljs-params">(Job job)</span> </span>{
      <span class="hljs-keyword">switch</span> (job) {
          <span class="hljs-keyword">case</span> Author a -&gt; System.out.println(<span class="hljs-string">"Author"</span>);
          <span class="hljs-keyword">case</span> Teacher t -&gt; System.out.println(<span class="hljs-string">"Teacher"</span>);
      }
<span class="hljs-comment">// 编译通过，若缺失case Teacher分支或者case Author分支，则编译错误</span>
</code></pre>
<h4 id="heading-virtual-thread">虚拟线程（Virtual Thread）</h4>
<p>虚拟线程是一种用户态的轻量级线程，类似于其他语言的协程，它的显著提高了Java程序的并发支持能力。细节请参考笔者另一篇文章：<a target="_blank" href="https://www.renxinblog.cn/docs/101_java/concurrent_programming/introduction/">理解虚拟线程</a></p>
<h4 id="heading-httpreadrenxinblogcn202504blog-posthtmlhttpapi"><a target="_blank" href="http://read.renxinblog.cn/2025/04/blog-post.html">新的</a>HTTP客户端API</h4>
<p>支持同步<a target="_blank" href="http://read.renxinblog.cn/2025/04/blog-post.html">调用和异步调</a>用，异步调用使用CompletableFuture来返回结果。</p>
<pre><code class="lang-java"><span class="hljs-comment">// 同步调用</span>
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(<span class="hljs-string">"https://httpbin.org/get"</span>))
        .GET()
        .build();
HttpResponse&lt;String&gt; response = client.send(request, HttpResponse.BodyHandlers.ofString());

<span class="hljs-comment">// 异步调用</span>
CompletableFuture&lt;String&gt; stringBodyCompletableFuture = client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body);
</code></pre>
<h4 id="heading-instance-of">instance of 模式匹配</h4>
<p>instance of 语法增强，可以省去类型转换步骤。</p>
<pre><code class="lang-java"><span class="hljs-comment">// jdk8写法</span>
String obj = <span class="hljs-string">"read.renxinblog.cn"</span>;
    <span class="hljs-keyword">if</span>(obj <span class="hljs-keyword">instanceof</span> String){
String s = (String) obj;
        System.out.

println(s.length());
        }

<span class="hljs-comment">// jdk21写法</span>
<span class="hljs-keyword">var</span> obj = <span class="hljs-string">"read.renxinblog.cn"</span>;
    <span class="hljs-keyword">if</span>(obj <span class="hljs-keyword">instanceof</span>
String s){
        System.out.

println(s.length());
        }
</code></pre>
<h4 id="heading-gczgc">新一代GC：ZGC</h4>
<p>相较于上一代的G1，ZGC的性能更加优秀，同时也更加稳定。几乎所有GC阶段都并发进行，STW时间极短，这意味着GC暂停对应用程序造成的性能波动非常小。<br />能够支持更大的堆，最多达16TB，并且随着堆的增大，GC性能几乎没有降低，这对于数据密集型的大堆系统非常友好。<br />ZGC能够保证GC停顿时间可控，更容易实现系统的SLO要求。<br />更高的并发能力同时也意味着更高的CPU消耗。<br />总之，ZGC以复杂的技术实现换来了极低的延迟时间和大堆性能表现，是G1控制延迟的进化版。性能的提升也带来更高的CPU消耗，但这不是一个缺点，而是一个非常的选择。<br />其他<br />其他特性还包括Stream API的增强、集合工厂方法、文本块（字符串增强）、日期API增强等，这里不多做介绍。</p>
]]></content:encoded></item></channel></rss>