Как я и обещал, хотя и очень поздно, я вернулся с примерами кода из моей предыдущей статьи Java SE 9 … Что нового? Вы можете обратиться к предыдущей статье, чтобы понять недавно представленные функции на высоком уровне. В этой статье приведены заключительные примеры кода для каждой функции.
Вам также может понравиться:
Замечания SKP по Java / Java EE: Пересмотр функций Java SE 9, часть 1
Вы можете скачать образцы кода для следующих новых функций здесь . (Импортируйте как проект Eclipse, установите компилятор / среду как Java 9. Запустите основной класс «Java9Application», чтобы увидеть выходные данные / результаты примеров кода.)
B. Основные изменения библиотеки в Java 9 (продолжение)
09. Stack-Walking API
До Java 9 способ доступа к Stack Trace был очень ограничен и предоставлял всю информацию о дампе или стеке одновременно. Это было неэффективно и не позволяло никакой прямой фильтрации данных. С Java 9 был представлен Lazy StackWalker API . Это позволит получать данные на основе условий фильтрации и является более эффективным.
Джава
1
package com.techilashots.java9.features;
2
import java.lang.StackWalker.Option;
3
import java.util.List;
4
import java.util.stream.Collectors;
5
/**
7
* Stack Walker API is a new feature of Java 9, aimed at Improving Performance of the predecessor Stack Track Element,
8
* as also for providing a way to filter the Stack Elements, in case of Exception or to Understand Application Behavior.
9
* Although, there have been multiple changes, I am covering only Stack Frame Attributes and also the walk() method
10
* for Walking the Stack Frame.
11
*/
12
public class StackWalkingService {
13
14
private int databaseService() {
15
int x = 3;
17
// Usage 01: Walking All Stack Frames
19
System.out.println("Java 9 Stack Walker API — Showing All Stack Frames");
20
StackWalker stackWalker = StackWalker.getInstance();
21
stackWalker.forEach(System.out::println);
22
System.out.println("");
23
// Usage 02 : Filtering or Walking Stack Frames
25
System.out.println("Java 9 Stack Walker API — Walking / Filtering Stack Frames");
26
List<StackWalker.StackFrame> stackFrames;
27
stackFrames = stackWalker.walk(frames -> frames.limit(2).collect(Collectors.toList()));
28
stackFrames.forEach(System.out::println);
29
System.out.println("");
30
// Usage 03 : Show All Attributes of a Stack Frame
32
System.out.println("Java 9 Stack Walker API — Show All Attributes in Stack Frame");
33
StackWalker newWalker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
34
stackFrames = newWalker.walk(frames -> frames.limit(1).collect(Collectors.toList()));
35
stackFrames.forEach(sfRecord->
36
{
37
System.out.printf("[Bytecode Index] %d%n", sfRecord.getByteCodeIndex());
38
System.out.printf("[Class Name] %s%n", sfRecord.getClassName());
39
System.out.printf("[Declaring Class] %s%n", sfRecord.getDeclaringClass());
40
System.out.printf("[File Name] %s%n", sfRecord.getFileName());
41
System.out.printf("[Method Name] %s%n", sfRecord.getFileName());
42
System.out.printf("[Is Native] %b%n", sfRecord.isNativeMethod());
43
System.out.printf("[Line Number] %d%n", sfRecord.getLineNumber());
44
});
45
return x;
46
}
47
private float persistenceService() {
49
float x = databaseService();
50
return x;
51
}
52
private double businessService() {
54
double x = persistenceService();
55
return x;
56
}
57
private double presentationService() {
59
long x = (long) businessService();
60
return x;
61
}
62
public void uiDisplay() {
64
System.out.println("Java 9 Stack Walker API for Debugging and Application Behavior");
65
double x = presentationService();
66
System.out.println("\n[Method to Display On User Interface]");
67
System.out.println("Old MacDonald had a Farm. In that Farm, He had " + x + " Cows!");
68
}
69
/**
71
* @param args
72
*/
73
public static void main(String[] args) {
74
StackWalkingService stackWalkingService = new StackWalkingService();
75
stackWalkingService.uiDisplay();
76
}
77
}
10. Компактные струны
Хотя это не имеет внешних последствий для разработчика с точки зрения изменения синтаксиса или семантики - это может повлиять на то, как мы проектируем память и производительность. Текущее представление UTF-16 использует 2 байта для хранения . Большая часть строки содержит символы, которые имеют только латиницу-1 по своей природе.
Для символов Latin-1 требуется только 1 байт для хранения . В Java 9 хранилище строк было изменено для запуска с дополнительным флагом кодирования . Этот флаг указывает, содержит ли он символы ISO-8859-1 / Latin-1 или символы UTF-16. Согласно официальному слову, это должно привести к улучшенному использованию памяти и эффективному сборщику мусора, но с некоторой потерей производительности при пиковых нагрузках .
Компактные строки всегда включены в Java 9, но их можно отключить, передав VM Argument + XX: -CompactStrings
Следует отметить, что в Java 9 реализована реализация java.lang. Строка решает во время выполнения, должен ли размер хранилища быть 2 байтами или 1 байтом, в соответствии с фактическим размером строки (символ UTF-16 или Latin-1).
11. Spin-Wait Советы
Для многопоточных приложений это приводит к некоторым улучшениям производительности в условиях ожидания занятости или ожидания вращения. Обычно Ожидание занято выполняется для синхронизации некоторого состояния объекта между двумя или более инициаторами - Ожидание возникновения условия до начала или продолжения обработки. Thread.onSpinWait () был представлен как статический метод в классе Thread и может вызываться при необходимости в циклах ожидания занятости. Это позволит JVM выдавать инструкции процессора для некоторых системных архитектур, чтобы сократить время реакции в таких циклах ожидания вращения. а также уменьшить мощность, потребляемую основным потоком или аппаратным потоком . Это способствует общему энергопотреблению программы и, возможно,Разрешение другим ядрам или аппаратным потокам выполняться на более высоких скоростях в пределах одного и того же энергопотребления .
Джава
xxxxxxxxxx
1
package com.techilashots.java9.features;
2
import java.util.List;
4
import java.util.Vector;
5
/**
7
* For a Single Line Demonstration, I wrote the Non-Pure Threaded form of Producer-Consumer. Run the Code Multiple Times
8
* On a Machine, where you can Understand how the Temperature Changes and Extra Cooling Fan Kicks Off. Even though I did
9
* not do it myself, Take it up as an Experiment, by removing the Thread.onSpinWait() [Compare Before/After and also try
10
* with Data Set of 1 Million to 10 Million]
11
*
12
* Thread.onSpinWait() will Optimize Latency and Reduce/Optimize Power Consumption
13
*/
14
public class SpinWaitHints {
15
public static void main(String[] args) {
17
List<String> itemQueue = new Vector<String>();
18
Producer producer = new Producer(itemQueue);
19
Consumer consumer = new Consumer(itemQueue);
20
producer.start();
21
consumer.start();
22
}
23
}
24
class Producer extends Thread {
25
List<String> itemQueue;
27
Producer(List<String> itemQueue) {
28
this.itemQueue = itemQueue;
29
}
30
public void run() {
31
try {
32
produce();
33
} catch (InterruptedException e) {
34
e.printStackTrace();
35
}
36
}
37
public void produce() throws InterruptedException {
38
while (true) {
39
while (itemQueue.size() < 100000) // produce 1 lac items
40
{
41
String item = "Sumith Puri " + (itemQueue.size());
42
itemQueue.add(item);
43
System.out.println("Item Produced: " + item);
44
}
45
while (itemQueue.size() > 0) {
46
// spin waiting — x86 architectures will now optimize
47
Thread.onSpinWait();
48
}
49
}
50
}
51
}
52
class Consumer extends Thread {
54
List<String> itemQueue;
55
public Consumer(List<String> itemQueue) {
56
this.itemQueue = itemQueue;
57
}
58
public void consume() throws InterruptedException {
59
while (true) {
60
while (itemQueue.size() < 100000) {
61
// spin waiting — x86 architectures will now optimize
62
Thread.onSpinWait();
63
}
64
int x = itemQueue.size();
65
while (x >= 1) {
66
x = x — 1;
67
if (x >= 0) {
68
String item = itemQueue.remove(x);
69
System.out.println("Item Consumed: " + item);
70
}
71
}
72
if (itemQueue.size() > 0)
73
itemQueue.remove(0);
74
}
75
}
76
public void run() {
78
try {
79
consume();
80
} catch (InterruptedException e) {
81
e.printStackTrace();
82
}
83
}
84
}
12. Новая версия-String Scheme
Начиная с Java 9, $ MAJOR. $ MINOR. $ SECURITY. $ PATCH - это схема именования выпусков в Java. Эти детали также содержатся в классе Runtime.Version. Начиная с Java 9, $ MAJOR. $ MINOR. $ SECURITY. $ PATCH - это схема именования выпусков в Java. Эти детали также содержатся в классе Runtime.Version.
Джава
xxxxxxxxxx
1
package com.techilashots.java9.features;
2
/**
3
* $MAJOR.$MINOR.$SECURITY+$BUILD is the Naming Scheme for Version String in Java.
4
*/
5
public class JavaVersionStringChanges {
6
public void printVersionInformation() {
7
Runtime.Version versionInfo = Runtime.version();
8
System.out.println("Version String Changes in Java 9");
9
System.out.println("Major Version: " + versionInfo.major());
10
System.out.println("Minor Version: " + versionInfo.minor());
11
System.out.println("Security Version: " + versionInfo.security());
12
System.out.println("Build Version: " + versionInfo.build());
13
System.out.println("\nIn Java 9, Version Naming is Major.Minor.Security.Build");
14
System.out.println("Currently Running in Java Version: " + versionInfo.toString());
15
}
16
public static void main(String[] args) {
17
new JavaVersionStringChanges().printVersionInformation();
18
}
19
}
13. Улучшенные дескрипторы метода
Дескриптор метода - это типизированная, непосредственно исполняемая ссылка на базовый метод, конструктор, поле или аналогичную низкоуровневую операцию с необязательными преобразованиями аргументов или возвращаемых значений. Эти преобразования являются достаточно общими и включают такие шаблоны, как преобразование , вставка , удаление и замена . В Java 9 дескрипторы методов были улучшены, чтобы включить статические методы для создания другого типа дескрипторов методов.
Джава
xxxxxxxxxx
1
package com.techilashots.java9.features;
2
import java.lang.invoke.MethodHandle;
3
import java.lang.invoke.MethodHandles;
4
/**
6
* MethodHandles were introduced first in Java 7. You have to think them as an alternative for Java Reflection API, but
7
* with an advantage of better performance as they are specified at creation time. Enhanced Method Handles has primarily
8
* added new static methods to better/widen the functionality provided by Method Handles.
9
*
10
* Note that Method Handles are Enhanced in Java 9, to introduce very many changes and methods. I will be covering the
11
* ones that are the most important, only to introduce this topic.
12
*
13
* arrayLength, arrayConstructor, zero, empty,
14
* loop, countedloop, iteratedloop, dowhileloop, whileloop, try/finally
15
*/
16
public class EnhancedMethodHandles {
17
public void enhancedMethodHandleDemo() {
19
try {
21
22
// arrayLenth
23
MethodHandle methodHandleLength = MethodHandles.arrayLength(int[].class);
24
int[] ageArray = new int[] { 21, 28, 36 };
25
int arrayLength;
26
arrayLength = (int) methodHandleLength.invoke(ageArray);
27
System.out.println("Length of Array using Method Handle is " + arrayLength);
28
29
// arrayConstructor
30
MethodHandle methodHandleConstructor = MethodHandles.arrayConstructor(int[].class);
31
int[] newAgeArray = (int[]) methodHandleConstructor.invoke(3);
32
System.out.println("Array Constructed using Method Handle of Size " + newAgeArray.length);
33
34
// zero
35
int x = (int) MethodHandles.zero(int.class).invoke();
36
System.out.println("Default Value of Primitive Integer using Method Handles is " + x);
37
String y = (String) MethodHandles.zero(String.class).invoke();
38
System.out.println("Default Value of String using Method Handles is " + y);
39
40
System.out.println();
41
System.out.println("Reader/Developer - Left as an Exercise for You :-)");
42
System.out.println("Refer Loop, CountedLoop, DoWhileLoop, WhileLoop, IteratedLoop, TryFinally");
43
} catch (Throwable e) {
44
45
System.out.println("Was Hungry as Ever - Gulped Everything I Got!");
46
}
47
// refer to, https://goo.gl/JCyo7N (official javadoc)
48
// also use, https://goo.gl/i8wNJ8 (individual blog)
49
}
50
public static void main(String[] args) {
52
new EnhancedMethodHandles().enhancedMethodHandleDemo();
53
}
54
}
14. Переменные ручки
Параллельный пакет Java (java.util.concurrent.atomic) предоставляет все атомарные типы для выполнения атомарных операций. Помимо этого, небезопасные операции (sun.misc.unsafe), такие как создание объектов без вызова конструктора, используемого в низкоуровневом программировании Java, должны быть скрыты от внешнего мира согласно JEP 260: инкапсуляция большинства внутренних API-интерфейсов .
Это привело к созданию нового абстрактного типа класса с именем VarHandle - это позволит разработчику назначать разные типы для одной и той же ссылки (динамически типизированной ссылки). Он также может позаботиться о выполнении атомарных операций с хранимой переменной, включая операции сравнения и замены (установки или обмена). Он также обеспечивает операции ограждения памяти, чтобы упорядочить представление объекта в памяти, обеспечивая более точное управление зернистостью.
Во-первых, вы должны понимать эффекты упорядочения памяти, поскольку VarHandle полностью основан на понимании простых, непостоянных , непрозрачных, режимов упорядочения памяти. Вы можете обратиться к ним по адресу https://www.baeldung.com/java-variable-handles (под эффектами упорядочения памяти). Вы должны попытаться визуализировать это правильно, а затем перейти к примерам кода.
Джава
xxxxxxxxxx
1
package com.techilashots.java9.features;
2
import java.lang.invoke.MethodHandles;
4
import java.lang.invoke.VarHandle;
5
/**
7
* VarHandle allows developers to assign different types to the same reference (dynamically typed reference).It can also
8
* take care of performing atomic operations on the held variable, including compare and swap (set/exchange) operations.
9
* It also provides memory fencing operations, to order the in-memory representation of the object, by providing finer
10
* grain control.
11
*
12
* I am providing an Example of the Read Operations using VarHandle. Please refer to the link provided below for further
13
* info on VarHandle on Public Variable, VarHandle for Private Variables, VarHandle for Array Types
14
*
15
* https://www.baeldung.com/java-variable-handles
16
*/
17
class VarHandleStore {
18
public int varIntHandle01 = 5;
20
public int varIntHandle02 = 9;
21
public byte varByteHandle03 = 21;
22
}
23
public class VariableHandles {
25
public void useVariableHandle() {
27
System.out.println("Java 9 Introduces.... Variable Handles!");
29
try {
31
VarHandleStore varHandleStore = new VarHandleStore();
33
VarHandle varHandle = MethodHandles.lookup().in(VarHandleStore.class).findVarHandle(VarHandleStore.class,
34
"varIntHandle01", int.class);
35
// value using get() in varhandle
36
int plainValue = (int) varHandle.get(varHandleStore);
37
System.out.println("Value using get() in VarHandle: " + plainValue);
38
// value is written to using set() — plain access
40
// you can also use set(), setOpaque(), setVolatile(), setRelease()
41
varHandle.set(varHandleStore, 21);
42
plainValue = (int) varHandle.get(varHandleStore);
43
System.out.println("Set Value using set(), then get() in VarHandle: " + plainValue);
44
45
// value is written to using getandadd()
46
int oldValue = (int) varHandle.getAndAdd(varHandleStore, 51);
47
plainValue = (int) varHandle.get(varHandleStore);
48
System.out.println("Using getAndAdd() in VarHandle, Old Value: " + oldValue + ", New Value: " + plainValue);
49
varHandle = MethodHandles.lookup().in(VarHandleStore.class).findVarHandle(VarHandleStore.class,
50
"varIntHandle02", int.class);
51
52
// please do try out the compareandset() — atomic updates
53
// have left this due to time constraints
54
// value is written to using getandbitwiseor()
55
varHandle = MethodHandles.lookup().in(VarHandleStore.class).findVarHandle(VarHandleStore.class,
56
"varByteHandle03", byte.class);
57
byte before = (byte) varHandle.getAndBitwiseOr(varHandleStore, (byte) 127);
58
byte after = (byte) varHandle.get(varHandleStore);
59
60
System.out.println("Get Byte Value, Then Or, using getAndBitwiseOr()");
61
System.out.println("Old Byte Value: " + before + "; New Byte Value: " + after);
62
} catch (NoSuchFieldException | IllegalAccessException e) {
63
64
e.printStackTrace();
65
}
66
}
67
public static void main(String[] args) {
69
new VariableHandles().useVariableHandle();
70
}
71
}
15. Фильтруйте входящие данные сериализации
Эта функция связана с добавлением фильтров при сериализации входящих потоков для повышения безопасности и надежности. Основным механизмом является интерфейс фильтра, реализованный клиентами сериализации и установленный в ObjectInputStream .
Методы интерфейса фильтра вызываются во время процесса десериализации для проверки десериализованных классов, размеров создаваемых массивов и метрик, описывающих длину потока, глубину потока и количество ссылок в процессе декодирования потока.
Фильтр возвращает статус, чтобы принять, отклонить или оставить статус неопределенным. Некоторую полезную информацию об этой функции можно найти по адресу https://goo.gl/bRezWt. Вы должны помнить слова Безопасность, Уязвимости и Надежность в качестве основных причин создания этой функции в Java. Это предотвратит возможные атаки безопасности, такие как отказ в обслуживании .
Основным механизмом является интерфейс фильтра, реализованный клиентами сериализации и установленный в ObjectInputStream . Методы интерфейса фильтра вызываются во время процесса десериализации для проверки десериализованных классов, размеров создаваемых массивов, длины потока, глубины графика и количества ссылок по мере декодирования потока.
Фильтр определяет, разрешены ли аргументы или отклонен, и должен возвращать соответствующий статус. Если фильтр не может определить статус, он должен вернуть UNDECIDED. Фильтры предназначены для конкретного случая использования и ожидаемых типов. Фильтру, предназначенному для конкретного пользователя, может быть передан класс, который находится вне области действия фильтра. Если, например, цель фильтра состоит в том, чтобы занести в черный список классы, он может отклонить класс-кандидат, который соответствует, и сообщить о невыполненных для других.
Джава
xxxxxxxxxx
1
package com.techilashots.java9.features;
2
import java.io.ObjectInputFilter;
4
/**
6
* Demonstrates Java 9 Serialization/De-Serialization Filters for Incoming Data. Do Refer https://goo.gl/bRezWt for more
7
* on Filters, with more Details and Examples.
8
*/
9
class ItemCatalogFilter implements ObjectInputFilter {
10
private long maxStreamBytes = 400; // Maximum allowed bytes in the stream.
12
private long maxDepth = 2; // Maximum depth of the graph allowed.
13
private long maxReferences = 5; // Maximum number of references in a graph.
14
16
public Status checkInput(FilterInfo filterInfo) {
17
if (filterInfo.references() < 0 || filterInfo.depth() < 0 || filterInfo.streamBytes() < 0
19
|| filterInfo.references() > maxReferences || filterInfo.depth() > maxDepth
20
|| filterInfo.streamBytes() > maxStreamBytes) {
21
// reject this, as it seems malicious, incorrect or tampered with
22
return Status.REJECTED;
23
}
24
Class<?> clazz = filterInfo.serialClass();
26
if (clazz != null) {
27
if (CatalogCustomer.class == filterInfo.serialClass()) {
28
// we are expecting a customer of our product catalog
29
System.out.println("Incoming Serialization Data Verified for Structure and Vulnerabilities");
30
return Status.ALLOWED;
31
} else {
32
// seems like some tampered, unexpected or malicious data here
33
return Status.REJECTED;
34
}
35
}
36
// the status as undecided, when we cannot infer — or + for sure
38
// left for the developer to decide as per business/security process
39
return Status.UNDECIDED;
40
}
41
}
Вы можете
скачать образцы кода для следующих новых функций
здесь . (Импортируйте как проект Eclipse, установите компилятор / среду как Java 9. Убедитесь, что в вашей системе установлена Java 9 / JDK 9. Запустите основной класс «Java9Application», чтобы увидеть выходные данные / результаты примеров кода.)
Ознакомьтесь с выводом консоли Eclipse, приведенным ниже, от запуска приложения Java9Application (см. Примеры прилагаемого кода). Пожалуйста, обратитесь к отдельным классам, предоставляемым для каждой функции, чтобы лучше понять функции. Вперед - добавьте, измените, удалите, чтобы поэкспериментировать со всеми новыми функциями Java 9. Вывод для отмеченных функций [01-08] показан в части 1 статьи на Java SE 9 ... Что нового? [Образцы кода - 01/02] .
Джава
xxxxxxxxxx
1
================================
2
09. Stack Walking API
4
---------------------
5
Java 9 Stack Walker API for Debugging and Application Behavior
6
Java 9 Stack Walker API — Showing All Stack Frames
7
com.techilashots.java9.features.StackWalkingService.databaseService(StackWalkingService.java:23)
8
com.techilashots.java9.features.StackWalkingService.persistenceService(StackWalkingService.java:57)
9
com.techilashots.java9.features.StackWalkingService.businessService(StackWalkingService.java:63)
10
com.techilashots.java9.features.StackWalkingService.presentationService(StackWalkingService.java:69)
11
com.techilashots.java9.features.StackWalkingService.uiDisplay(StackWalkingService.java:77)
12
com.techilashots.java9.main.Java9Application.stackWalkingAPI(Java9Application.java:321)
13
com.techilashots.java9.main.Java9Application.java9CoreLibraryChanges(Java9Application.java:106)
14
com.techilashots.java9.main.Java9Application.main(Java9Application.java:48)
15
Java 9 Stack Walker API — Walking / Filtering Stack Frames
16
com.techilashots.java9.features.StackWalkingService.databaseService(StackWalkingService.java:30)
17
com.techilashots.java9.features.StackWalkingService.persistenceService(StackWalkingService.java:57)
18
Java 9 Stack Walker API — Show All Attributes in Stack Frame
19
[Bytecode Index] 112
20
[Class Name] com.techilashots.java9.features.StackWalkingService
21
[Declaring Class] class com.techilashots.java9.features.StackWalkingService
22
[File Name] StackWalkingService.java
23
[Method Name] StackWalkingService.java
24
[Is Native] false
25
[Line Number] 38
26
[Method to Display On User Interface]
27
Old MacDonald had a Farm. In that Farm, He had 3.0 Cows!
28
================================
30
11. Spin Wait Hints
32
-------------------
33
Spin Wait Hints Makes Power Consumption Efficient
34
[Uncomment Method Call in Code, To Run (Non-Terminating) Demo]
35
================================
37
12. Java Version Naming
39
----------------------
40
Java 9 changes the way Java Version String Format
41
Version String Changes in Java 9
42
Major Version: 9
43
Minor Version: 0
44
Security Version: 4
45
Build Version: Optional[11]
46
In Java 9, Version Naming is Major.Minor.Security.Build
47
Currently Running in Java Version: 9.0.4+11
48
================================
50
13. Enhanced Method Handles
52
---------------------------
53
Java 9 has Enhanced Method Handles for Multitude of Operations
54
Length of Array using Method Handle is 3
55
Array Constructed using Method Handle of Size 3
56
Default Value of Primitive Integer using Method Handles is 0
57
Default Value of String using Method Handles is null
58
Reader/Developer — Left as an Exercise for You :-)
59
Refer Loop, CountedLoop, DoWhileLoop, WhileLoop, IteratedLoop, TryFinally
60
================================
62
14. Variable Handles
64
--------------------
65
Java 9 Introduces Variable Handles, Different Types for Same Reference
66
Java 9 Introduces.... Variable Handles!
67
Value using get() in VarHandle: 5
68
Set Value using set(), then get() in VarHandle: 21
69
Using getAndAdd() in VarHandle, Old Value: 21, New Value: 72
70
Get Byte Value, Then Or, using getAndBitwiseOr()
71
Old Byte Value: 21; New Byte Value: 127
72
================================
74
15. Filter Incoming Serialization Data
76
-------------------------------------
77
Java 9 Allows Filtering of Serialization Data, through Object Input Filters
78
Incoming Serialization Data Verified for Structure and Vulnerabilities
79
Customer Details String Follows (Filtered then De-Serialized)
80
skp:skp:4240123488889001:1.243223256E7
81
================================
16. Больше обновлений параллелизма
[Будет рассмотрено в отдельной статье, так как существует много изменений для освещения и заслуживает статья сама по себе]
[Обратите внимание, что в другой статье я расскажу о модульности Java 9 - Project Jigsaw. Следующие темы / изменения с примерами кода будут рассмотрены в этой статье]
JEP 220: модульные образы времени выполнения JEP 260: инкапсулирует большинство внутренних API
Удачного кодирования с Java 9!