JAVA9琐碎特性
Java9相关记录
https://gitee.com/bgt0314/java-9
模块化系统运行影像
示例 System.out.println(ClassLoader.getSystemResource("java/lang/Class.class"));
- jdk8执行结果:
jar:file:/D:/BaiduNetdiskDownload/jdk1.8.0_45/jre/lib/rt.jar!/java/lang/Class.class
- jdk9执行结果:
jrt:/java.base/java/lang/Class.class
查看源码发现,jdk9新增了Loader类,并在其中getResource加入了模块化相关的逻辑
@Override public URL findResource(String name) { String pn = Resources.toPackageName(name); LoadedModule module = localPackageToModule.get(pn); if (module != null) { try { URL url = findResource(module.name(), name); if (url != null && (name.endsWith(".class") || url.toString().endsWith("/") || isOpen(module.mref(), pn))) { return url; } } catch (IOException ioe) { // ignore } } else { for (ModuleReference mref : nameToModule.values()) { try { URL url = findResource(mref.descriptor().name(), name); if (url != null) return url; } catch (IOException ioe) { // ignore } } } return null; }
下划线_标识符的改变
在Java8中_是可以作为变量名使用,只不过会警告,在Java9则是错误
try-with-resources改善
- 9之前
InputStream inputStream = new FileInputStream("test.txt"); try (InputStream stream = inputStream) {} catch (IOException e) {}InputStream inputStream = new FileInputStream("test.txt"); try (InputStream stream = inputStream) {} catch (IOException e) {}
- 9
InputStream inputStream = new FileInputStream("test.txt"); try (inputStream) {} catch (IOException e) {}
接口支持private方法
示例:
public interface RickyInterface{ public void setUp(); private static void printInterfaceName(){ System.out.println("RickyInterface"); } public static void displayInterfaceName(){ printInterfaceName(); } }
匿名内部类的菱形操作符
- Java7是我们可以这样使用<>
List<String> list1 = new ArrayList<String>(); List<String> list2 = new ArrayList<>();
- java9中我们可以对匿名内部类使用
Iterator <String> iter = new Iterator <> () { @Override public boolean hasNext() { return false; } @Override public String next() { return null; } };
Java9中的Flow(生产者消费者)
以下为官方示例
package com.ricky.flow; import java.util.concurrent.ExecutorService; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.Flow.*; import java.util.function.Consumer; /** java9中新增的生产者消费者 以下是官方示例(源码中的用法) * */ public class FlowDemo { public static void main(String[] args) { OneShotPublisher publisher=new OneShotPublisher(); SampleSubscriber subscriber=new SampleSubscriber(10, new Consumer() { @Override public void accept(Object o) { if (o instanceof Boolean) { boolean b= (boolean) o; if (b) { System.out.println("开启任务执行"); } }else { System.out.println("其他非boolean情况"); } } }); publisher.subscribe(subscriber); publisher.subscribe(subscriber);//验证是否可以多次消费 try { Thread.currentThread().join(10);//避免执行失败 } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 一次性生产者 * * 消息控件-->生产者(发布者) */ class OneShotPublisher implements Publisher<Boolean> { private final ExecutorService executor = ForkJoinPool.commonPool(); // daemon-based private boolean subscribed; // 首次订阅后变为true 默认false 只能消费一次 /** * 推送消费者 * @param subscriber */ public synchronized void subscribe(Subscriber<? super Boolean> subscriber) { if (subscribed) subscriber.onError(new IllegalStateException()); // 只能消费一次 else { subscribed = true;//这里标示已经消费过了 subscriber.onSubscribe(new OneShotSubscription(subscriber, executor)); } } /*** * 消息控件-->链接者 */ static class OneShotSubscription implements Subscription { private final Subscriber<? super Boolean> subscriber; private final ExecutorService executor; private Future<?> future; // to allow cancellation private boolean completed; OneShotSubscription(Subscriber<? super Boolean> subscriber, ExecutorService executor) { this.subscriber = subscriber; this.executor = executor; } /** * 请求执行 * @param n */ public synchronized void request(long n) { System.out.println("请求:"+completed); if (n != 0 && !completed) { completed = true; if (n < 0) { IllegalArgumentException ex = new IllegalArgumentException(); executor.execute(() -> subscriber.onError(ex)); } else { future = executor.submit(() -> { subscriber.onNext(Boolean.TRUE); subscriber.onComplete(); }); } } } /** * 拒绝 */ public synchronized void cancel() { completed = true; if (future != null) future.cancel(false); } } } /** * 简单消费者 * * 消息控件-->消费者(接收者) * @param <T> */ class SampleSubscriber<T> implements Subscriber<T> { final Consumer<? super T> consumer; Subscription subscription; final long bufferSize; long count; SampleSubscriber(long bufferSize, Consumer<? super T> consumer) { this.bufferSize = bufferSize; this.consumer = consumer; } public void onSubscribe(Subscription subscription) { long initialRequestSize = bufferSize; count = bufferSize - bufferSize / 2; // re-request when half consumed (this.subscription = subscription).request(initialRequestSize); } public void onNext(T item) { if (--count <= 0) subscription.request(count = bufferSize - bufferSize / 2); consumer.accept(item); } public void onError(Throwable ex) { ex.printStackTrace(); } public void onComplete() { System.out.println("hi,ricky bai,your task complete"); } } /** * 自由消费者 * @param <T> */ class UnboundedSubscriber<T> implements Subscriber<T> { public void onSubscribe(Subscription subscription) { subscription.request(Long.MAX_VALUE); // effectively unbounded } public void onNext(T item) { use(item); } public void onError(Throwable ex) { ex.printStackTrace(); } public void onComplete() {} void use(T item) {} }
JavaDoc
Deprecated注解 改善
- Java9之前的
package java.lang; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; /** * A program element annotated @Deprecated is one that programmers * are discouraged from using, typically because it is dangerous, * or because a better alternative exists. Compilers warn when a * deprecated program element is used or overridden in non-deprecated code. * * @author Neal Gafter * @since 1.5 * @jls 9.6.3.6 @Deprecated */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Deprecated { }
- Java9
package java.lang; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; /** * A program element annotated {@code @Deprecated} is one that programmers * are discouraged from using. An element may be deprecated for any of several * reasons, for example, its usage is likely to lead to errors; it may * be changed incompatibly or removed in a future version; it has been * superseded by a newer, usually preferable alternative; or it is obsolete. * * <p>Compilers issue warnings when a deprecated program element is used or * overridden in non-deprecated code. Use of the {@code @Deprecated} * annotation on a local variable declaration or on a parameter declaration * or a package declaration has no effect on the warnings issued by a compiler. * * <p>When a module is deprecated, the use of that module in {@code * requires}, but not in {@code exports} or {@code opens} clauses causes * a warning to be issued. A module being deprecated does <em>not</em> cause * warnings to be issued for uses of types within the module. * * <p>This annotation type has a string-valued element {@code since}. The value * of this element indicates the version in which the annotated program element * was first deprecated. * * <p>This annotation type has a boolean-valued element {@code forRemoval}. * A value of {@code true} indicates intent to remove the annotated program * element in a future version. A value of {@code false} indicates that use of * the annotated program element is discouraged, but at the time the program * element was annotated, there was no specific intent to remove it. * * @apiNote * It is strongly recommended that the reason for deprecating a program element * be explained in the documentation, using the {@code @deprecated} * javadoc tag. The documentation should also suggest and link to a * recommended replacement API, if applicable. A replacement API often * has subtly different semantics, so such issues should be discussed as * well. * * <p>It is recommended that a {@code since} value be provided with all newly * annotated program elements. Note that {@code since} cannot be mandatory, * as there are many existing annotations that lack this element value. * * <p>There is no defined order among annotation elements. As a matter of * style, the {@code since} element should be placed first. * * <p>The {@code @Deprecated} annotation should always be present if * the {@code @deprecated} javadoc tag is present, and vice-versa. * * @author Neal Gafter * @since 1.5 * @jls 9.6.4.6 @Deprecated */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE}) public @interface Deprecated { /** * Returns the version in which the annotated element became deprecated. * The version string is in the same format and namespace as the value of * the {@code @since} javadoc tag. The default value is the empty * string. * * @return the version string * @since 9 */ String since() default ""; /** * Indicates whether the annotated element is subject to removal in a * future version. The default value is {@code false}. * * @return whether the element is subject to removal * @since 9 */ boolean forRemoval() default false; }
ProcessHandle
- 示例
package com.ricky.processhandle; public class ProcessHandleDemo { public static void main(String[] args) { System.out.println("PID:"+ProcessHandle.current().pid()); System.out.println("info:"+ProcessHandle.current().info()); System.out.println("子进程:"+ProcessHandle.current().children()); System.out.println("是否存活:"+ProcessHandle.current().isAlive()); System.out.println("父进程:"+ProcessHandle.current().parent()); System.out.println("快照:"+ProcessHandle.current().descendants()); } }
- 执行结果
PID:17540 info:[user: Optional[RICKY\baiguantao], cmd: D:\Program Files\Java\jdk-9\bin\java.exe, startTime: Optional[2017-11-23T09:28:11.459Z], totalTime: Optional[PT0.3276021S]] 子进程:[email protected] 是否存活:true 父进程:Optional[11432] 快照:[email protected]
UTF-8 Property Files
在Java9中,编码从ISO-8859-1转为UTF-8 。
交流群:244930845
转载于:https://my.oschina.net/lt0314/blog/1581479