news 2026/4/27 8:23:18

JDK9版本新增特性

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JDK9版本新增特性

语法层面

钻石操作符

代码示例

package com.sumlv.javase.note; /** * 示例代码 * * @Auther: yuzhuo.song * @Date: 2025-03-14 */ public class Demo { public static void main(String[] args) { Person<String> person = new Person<>() { @Override public void eat(String s) { System.out.println("person eat: " + s); } }; } } interface Person<T> { void eat(T t); }

特性说明

在JDK9之前的版本中,创建带有泛型的匿名内部类时,new后面的钻石操作符中的泛型是必须要写的,如果不写会报错(Cannot use '<>' with anonymous inner classes)。

在JDK9中对其进行优化,创建带有泛型的匿名内部类时,new后面的钻石操作符中的泛型可以省略。

try语法升级

代码示例

package com.sumlv.javase.note; import java.io.*; /** * 示例代码 * * @Auther: yuzhuo.song * @Date: 2025-03-14 */ public class Demo { public static void main(String[] args) throws FileNotFoundException { OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("D:/a.txt")); InputStreamReader in = new InputStreamReader(new FileInputStream("D:/b.txt")); try(in; out) { // IO操作 } catch (Exception e) { e.printStackTrace(); } } }

特性说明

在jdk8版本中已经对try的语法进行过一次升级,定义在try后面小括号中的对象可以不再手动关闭,但该对象所属类需要实现AutoCloseable接口。

在JDK9中对try的语法再次进行了升级,try后面的小括号中可以直接使用已经在try外面定义好的对象(多个对象使用 ; 进行分隔),其效果依旧与将对象直接定义在小括号中一样。

接口私有方法

代码示例

package com.sumlv.javase.note; /** * 示例代码 * * @Auther: yuzhuo.song * @Date: 2025-03-14 */ public class Demo { public static void main(String[] args) { TestInterface test = new TestClass(); test.test(); } } class TestClass implements TestInterface { } interface TestInterface { default void test() { privateMethod(); } private void privateMethod() { System.out.println("privateMethod"); } }

特性说明

在jdk8版本中已经对接口进行过一次升级(引入了静态方法和默认方法)。在JDK9中对接口再次进行了升级,引入了默认方法。

通过两个版本的升级可以明显感受到,接口和抽象类越来越接近了。但是由于接口多实现的特性使得我们在后续多态的使用中会更加灵活。

API层面

Stream新增takeWhile方法

代码示例

/** * Returns, if this stream is ordered, a stream consisting of the longest * prefix of elements taken from this stream that match the given predicate. * Otherwise returns, if this stream is unordered, a stream consisting of a * subset of elements taken from this stream that match the given predicate. * * <p>If this stream is ordered then the longest prefix is a contiguous * sequence of elements of this stream that match the given predicate. The * first element of the sequence is the first element of this stream, and * the element immediately following the last element of the sequence does * not match the given predicate. * * <p>If this stream is unordered, and some (but not all) elements of this * stream match the given predicate, then the behavior of this operation is * nondeterministic; it is free to take any subset of matching elements * (which includes the empty set). * * <p>Independent of whether this stream is ordered or unordered if all * elements of this stream match the given predicate then this operation * takes all elements (the result is the same as the input), or if no * elements of the stream match the given predicate then no elements are * taken (the result is an empty stream). * * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting * stateful intermediate operation</a>. * * @implSpec * The default implementation obtains the {@link #spliterator() spliterator} * of this stream, wraps that spliterator so as to support the semantics * of this operation on traversal, and returns a new stream associated with * the wrapped spliterator. The returned stream preserves the execution * characteristics of this stream (namely parallel or sequential execution * as per {@link #isParallel()}) but the wrapped spliterator may choose to * not support splitting. When the returned stream is closed, the close * handlers for both the returned and this stream are invoked. * * @apiNote * While {@code takeWhile()} is generally a cheap operation on sequential * stream pipelines, it can be quite expensive on ordered parallel * pipelines, since the operation is constrained to return not just any * valid prefix, but the longest prefix of elements in the encounter order. * Using an unordered stream source (such as {@link #generate(Supplier)}) or * removing the ordering constraint with {@link #unordered()} may result in * significant speedups of {@code takeWhile()} in parallel pipelines, if the * semantics of your situation permit. If consistency with encounter order * is required, and you are experiencing poor performance or memory * utilization with {@code takeWhile()} in parallel pipelines, switching to * sequential execution with {@link #sequential()} may improve performance. * * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>, * <a href="package-summary.html#Statelessness">stateless</a> * predicate to apply to elements to determine the longest * prefix of elements. * @return the new stream * @since 9 */ default Stream<T> takeWhile(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); // Reuses the unordered spliterator, which, when encounter is present, // is safe to use as long as it configured not to split return StreamSupport.stream( new WhileOps.UnorderedWhileSpliterator.OfRef.Taking<>(spliterator(), true, predicate), isParallel()).onClose(this::close); }

特性说明

在JDK9中,stream新增了takeWhileAPI,其作用是从头开始获取数据,直到遇到不满足条件的数据时停止。

Stream新增dropWhile方法

代码示例

/** * Returns, if this stream is ordered, a stream consisting of the remaining * elements of this stream after dropping the longest prefix of elements * that match the given predicate. Otherwise returns, if this stream is * unordered, a stream consisting of the remaining elements of this stream * after dropping a subset of elements that match the given predicate. * * <p>If this stream is ordered then the longest prefix is a contiguous * sequence of elements of this stream that match the given predicate. The * first element of the sequence is the first element of this stream, and * the element immediately following the last element of the sequence does * not match the given predicate. * * <p>If this stream is unordered, and some (but not all) elements of this * stream match the given predicate, then the behavior of this operation is * nondeterministic; it is free to drop any subset of matching elements * (which includes the empty set). * * <p>Independent of whether this stream is ordered or unordered if all * elements of this stream match the given predicate then this operation * drops all elements (the result is an empty stream), or if no elements of * the stream match the given predicate then no elements are dropped (the * result is the same as the input). * * <p>This is a <a href="package-summary.html#StreamOps">stateful * intermediate operation</a>. * * @implSpec * The default implementation obtains the {@link #spliterator() spliterator} * of this stream, wraps that spliterator so as to support the semantics * of this operation on traversal, and returns a new stream associated with * the wrapped spliterator. The returned stream preserves the execution * characteristics of this stream (namely parallel or sequential execution * as per {@link #isParallel()}) but the wrapped spliterator may choose to * not support splitting. When the returned stream is closed, the close * handlers for both the returned and this stream are invoked. * * @apiNote * While {@code dropWhile()} is generally a cheap operation on sequential * stream pipelines, it can be quite expensive on ordered parallel * pipelines, since the operation is constrained to return not just any * valid prefix, but the longest prefix of elements in the encounter order. * Using an unordered stream source (such as {@link #generate(Supplier)}) or * removing the ordering constraint with {@link #unordered()} may result in * significant speedups of {@code dropWhile()} in parallel pipelines, if the * semantics of your situation permit. If consistency with encounter order * is required, and you are experiencing poor performance or memory * utilization with {@code dropWhile()} in parallel pipelines, switching to * sequential execution with {@link #sequential()} may improve performance. * * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>, * <a href="package-summary.html#Statelessness">stateless</a> * predicate to apply to elements to determine the longest * prefix of elements. * @return the new stream * @since 9 */ default Stream<T> dropWhile(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); // Reuses the unordered spliterator, which, when encounter is present, // is safe to use as long as it configured not to split return StreamSupport.stream( new WhileOps.UnorderedWhileSpliterator.OfRef.Dropping<>(spliterator(), true, predicate), isParallel()).onClose(this::close); }

特性说明

在JDK9中,stream新增了dropWhileAPI,其作用是从头开始删除数据,直到遇到不满足条件的数据时停止。

Stream新增ofNullable方法

代码示例

/** * Returns a sequential {@code Stream} containing a single element, if * non-null, otherwise returns an empty {@code Stream}. * * @param t the single element * @param <T> the type of stream elements * @return a stream with a single element if the specified element * is non-null, otherwise an empty stream * @since 9 */ public static<T> Stream<T> ofNullable(T t) { return t == null ? Stream.empty() : StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false); }

特性说明

在JDK9中,stream新增了ofNullableAPI。其作用是创建一个stream时,如果对象是null则返回一个空stream(在之前的版本中调用of方法,如果对象是null,会报空指针异常)。

Stream新增iterate方法

代码示例

/** * Returns an infinite sequential ordered {@code Stream} produced by iterative * application of a function {@code f} to an initial element {@code seed}, * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)}, * {@code f(f(seed))}, etc. * * <p>The first element (position {@code 0}) in the {@code Stream} will be * the provided {@code seed}. For {@code n > 0}, the element at position * {@code n}, will be the result of applying the function {@code f} to the * element at position {@code n - 1}. * * <p>The action of applying {@code f} for one element * <a href="../concurrent/package-summary.html#MemoryVisibility"><i>happens-before</i></a> * the action of applying {@code f} for subsequent elements. For any given * element the action may be performed in whatever thread the library * chooses. * * @param <T> the type of stream elements * @param seed the initial element * @param f a function to be applied to the previous element to produce * a new element * @return a new sequential {@code Stream} */ public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) { Objects.requireNonNull(f); Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.IMMUTABLE) { T prev; boolean started; @Override public boolean tryAdvance(Consumer<? super T> action) { Objects.requireNonNull(action); T t; if (started) t = f.apply(prev); else { t = seed; started = true; } action.accept(prev = t); return true; } }; return StreamSupport.stream(spliterator, false); }

特性说明

在JDK8中,stream已经存在一个iterateAPI。在JDK9中又对其进了重载,通过示例代码可知,约等于stream中的for循环。

InputStream新增transferTo方法

代码示例

/** * Reads all bytes from this input stream and writes the bytes to the * given output stream in the order that they are read. On return, this * input stream will be at end of stream. This method does not close either * stream. * <p> * This method may block indefinitely reading from the input stream, or * writing to the output stream. The behavior for the case where the input * and/or output stream is <i>asynchronously closed</i>, or the thread * interrupted during the transfer, is highly input and output stream * specific, and therefore not specified. * <p> * If the total number of bytes transferred is greater than {@linkplain * Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned. * <p> * If an I/O error occurs reading from the input stream or writing to the * output stream, then it may do so after some bytes have been read or * written. Consequently the input stream may not be at end of stream and * one, or both, streams may be in an inconsistent state. It is strongly * recommended that both streams be promptly closed if an I/O error occurs. * * @param out the output stream, non-null * @return the number of bytes transferred * @throws IOException if an I/O error occurs when reading or writing * @throws NullPointerException if {@code out} is {@code null} * * @since 9 */ public long transferTo(OutputStream out) throws IOException { Objects.requireNonNull(out, "out"); long transferred = 0; byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int read; while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) { out.write(buffer, 0, read); if (transferred < Long.MAX_VALUE) { try { transferred = Math.addExact(transferred, read); } catch (ArithmeticException ignore) { transferred = Long.MAX_VALUE; } } } return transferred; }

特性说明

看代码可知,其作用就是将输入流中的内容输出到输出流中。

集合新增of方法

代码示例

/** * Returns an unmodifiable list containing an arbitrary number of elements. * See <a href="#unmodifiable">Unmodifiable Lists</a> for details. * * @apiNote * This method also accepts a single array as an argument. The element type of * the resulting list will be the component type of the array, and the size of * the list will be equal to the length of the array. To create a list with * a single element that is an array, do the following: * * <pre>{@code * String[] array = ... ; * List<String[]> list = List.<String[]>of(array); * }</pre> * * This will cause the {@link List#of(Object) List.of(E)} method * to be invoked instead. * * @param <E> the {@code List}'s element type * @param elements the elements to be contained in the list * @return a {@code List} containing the specified elements * @throws NullPointerException if an element is {@code null} or if the array is {@code null} * * @since 9 */ @SafeVarargs @SuppressWarnings("varargs") static <E> List<E> of(E... elements) { switch (elements.length) { // implicit null check of elements case 0: @SuppressWarnings("unchecked") var list = (List<E>) ImmutableCollections.EMPTY_LIST; return list; case 1: return new ImmutableCollections.List12<>(elements[0]); case 2: return new ImmutableCollections.List12<>(elements[0], elements[1]); default: return ImmutableCollections.listFromArray(elements); } }

特性说明

看代码可知,其作用就是返回了一个只读集合。of的重载方法很多,使用中可以根据实际调用的方法查看源码。

Optional新增stream方法

代码示例

/** * If a value is present, returns a sequential {@link Stream} containing * only that value, otherwise returns an empty {@code Stream}. * * @apiNote * This method can be used to transform a {@code Stream} of optional * elements to a {@code Stream} of present value elements: * <pre>{@code * Stream<Optional<T>> os = .. * Stream<T> s = os.flatMap(Optional::stream) * }</pre> * * @return the optional value as a {@code Stream} * @since 9 */ public Stream<T> stream() { if (isEmpty()) { return Stream.empty(); } else { return Stream.of(value); } }

特性说明

看代码可知,如果value为空,则返回一个空stream。如果value不为空,则返回一个只包含value的stream。

Optional新增or方法

代码示例

/** * If a value is present, returns an {@code Optional} describing the value, * otherwise returns an {@code Optional} produced by the supplying function. * * @param supplier the supplying function that produces an {@code Optional} * to be returned * @return returns an {@code Optional} describing the value of this * {@code Optional}, if a value is present, otherwise an * {@code Optional} produced by the supplying function. * @throws NullPointerException if the supplying function is {@code null} or * produces a {@code null} result * @since 9 */ public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) { Objects.requireNonNull(supplier); if (isPresent()) { return this; } else { @SuppressWarnings("unchecked") Optional<T> r = (Optional<T>) supplier.get(); return Objects.requireNonNull(r); } }

特性说明

看代码可知,如果value非空,则返回当前对象对应的optional。如果value为空,则返回supplier对应的optional。

Optional新增ifPresentOrElse方法

代码示例

/** * If a value is present, performs the given action with the value, * otherwise performs the given empty-based action. * * @param action the action to be performed, if a value is present * @param emptyAction the empty-based action to be performed, if no value is * present * @throws NullPointerException if a value is present and the given action * is {@code null}, or no value is present and the given empty-based * action is {@code null}. * @since 9 */ public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) { if (value != null) { action.accept(value); } else { emptyAction.run(); } }

特性说明

看代码可知,如果value非空,则使用value执行给定的操作,否则执行Runnable的操作。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 22:40:06

NIH-plug参数系统深度解析:声明式设计如何简化插件开发

NIH-plug参数系统深度解析&#xff1a;声明式设计如何简化插件开发 【免费下载链接】nih-plug Rust VST3 and CLAP plugin framework and plugins - because everything is better when you do it yourself 项目地址: https://gitcode.com/gh_mirrors/ni/nih-plug NIH-p…

作者头像 李华
网站建设 2026/4/17 12:06:47

如何5分钟掌握大麦网自动化抢票神器:DamaiHelper终极指南

如何5分钟掌握大麦网自动化抢票神器&#xff1a;DamaiHelper终极指南 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 还在为心仪演唱会门票秒光而烦恼吗&#xff1f;面对热门演出时&#xff0c;手…

作者头像 李华
网站建设 2026/4/17 14:32:05

React Most Wanted与Create React App深度对比:为什么选择RMW?

React Most Wanted与Create React App深度对比&#xff1a;为什么选择RMW&#xff1f; 【免费下载链接】react-most-wanted React starter kit with "Most Wanted" application features 项目地址: https://gitcode.com/gh_mirrors/re/react-most-wanted Reac…

作者头像 李华
网站建设 2026/4/21 3:15:56

行业标杆是怎样炼成的?深度解析乾妃卫浴 20 年不锈钢金属高定之路

在不锈钢家居赛道&#xff0c;能同时兼顾工艺、美学与高端定制的品牌寥寥无几&#xff0c;而乾妃卫浴凭借20余年深耕经验&#xff0c;从广东佛山走出&#xff0c;成为广东省卫浴商会不锈钢专业委员会副会长单位&#xff0c;更斩获多项行业大奖&#xff0c;成为高端人群定制不锈…

作者头像 李华
网站建设 2026/4/21 2:00:56

硬核来袭,Java全套学习资料(2026最新版)

别再拿旧资料瞎准备了&#xff01;看看我们这份联合2025-2026届成功入职头部企业的12位准大厂人&#xff0c;深挖近3个月一线互联网、科技公司的真实面经反馈、核心考察重点&#xff0c;把大厂面试官的提问逻辑、评分标准、高频考点全拆解&#xff0c;耗时打磨出这份「最新大厂…

作者头像 李华