Java 12 has already entered the Rampdown phase and its features are almost finalized and will be released on March 19th if all goes well. -> Was done. So, I will summarize the functions that enter Java 12 into JEP, API, and others. JDK 12 Early-Access Builds
JEP First of all, JEP-based changes that summarize major functions http://openjdk.java.net/projects/jdk/12/
Contains 8 JEPs in all. The three above and the Default CDS are likely to affect the average Java programmer. Unfortunately Raw String Literals have been dropped. 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental) 230: Microbenchmark Suite 325: Switch Expressions (Preview) 334: JVM Constants API 340: One AArch64 Port, Not Two 341: Default CDS Archives 344: Abortable Mixed Collections for G1 346: Promptly Return Unused Committed Memory from G1
I will write about each in the order in which they are likely to be used.
325: Switch Expressions (Preview)
The Switch statement has been extended as a Preview function and can now be used as an expression. (To use the Preview function, you need to add --enable-preview
to javac
etc.)
String time = switch (weekday) {
case MONDAY, FRIDAY -> "10:00-18:00";
case TUESDAY, THURSDAY -> "10:00-14:00";
default -> "holiday";
};
This looks like this until now.
String time;
switch (weekday) {
case MONDAY:
case FRIDAY:
time = "10:00-18:00";
break;
case TUESDAY:
case THURSDAY:
time = "10:00-14:00";
break;
default:
time = "holiday";
}
I think this is the pattern most of the time you use switch
. In the conventional switch, of course, the amount of description is large, but it has caused bugs such as break omission, updating the wrong variable, and not being guaranteed that there is no update omission. This will be resolved, so I would like to actively use it.
Actually, it is divided into three additional specifications.
You can now specify multiple values for case
.
String time;
switch (weekday) {
case MONDAY, FRIDAY:
time = "10:00-18:00";
break;
case TUESDAY, THURSDAY:
time = "10:00-14:00";
break;
default:
time = "holiday";
}
Rule Switch
By using ->
, break is no longer necessary.
String time;
switch (weekday) {
case MONDAY, FRIDAY -> time = "10:00-18:00";
case TUESDAY, THURSDAY -> time = "10:00-14:00";
default -> time = "holiday";
}
You can also process multiple lines using blocks.
String time;
switch (weekday) {
case MONDAY, FRIDAY -> {
var endTime = getEndTime();
time = "10:00-" + endTime;
}
case TUESDAY, THURSDAY -> time = "10:00-14:00";
default -> time = "holiday";
}
I want to use this positively.
And switch
became an expression.
If you don't use the arrow syntax, or if you use blocks in the arrow syntax, break
returns the value.
String time = switch (weekday) {
case MONDAY, FRIDAY -> {
var endTime = getEndTime();
break "10:00-" + endTime;
}
case TUESDAY, THURSDAY -> "10:00-14:00";
default -> "holiday";
};
An error will occur if all inputs cannot be supported.
jshell> switch("a"){ case "a" -> 3;}
|error:
|The switch expression does not cover all possible input values
| switch("a"){ case "a" -> 3;}
| ^--------------------------^
The break
that returns a value could be break-with
when it became official.
Call for feedback -- enhanced switch
However, in JDK 13, it is yield
.
341: Default CDS Archives
There is a mechanism to create class data in advance and share it, but until now it was necessary to create class data by yourself as java -Xshare: dump
.
From JDK12, lib / server / classes.jsa
is included in advance, so this work is unnecessary, and if -Xshare: auto
is the default in JDK11 and classes.jsa
exists, it will be automatic. Since CDS is used in, it seems that CDS is used from the beginning without doing anything.
This should improve Java startup time.
189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental) This is a GC developed by Red Hat. It seems that the stop time does not change whether it is 2GB or 200GB.
Since there are many codes in common with G1GC, it seems that G1GC could be improved during the development of Shenandoah. This JEP346 is also one of the reflections of such improvements during Shenandoah development in G1GC. Parallel Full GC for G1 in Java 10 seems to be the same. InfoQ: The Future of OpenJDK in Red Hat
By the way, JDK11 also contains two GCs, ZGC and Epsillon. So, JDK12 contains 7 GCs.
The default is from Java 9 to G1GC. JEP 248: Make G1 the Default Garbage Collector
However, it seems that Parallel GC is used in low memory environments and Serial GC is used in single core environments.
It seems better not to use ZGC with a heap of 32GB or less, so I think it is used when there is a heap of several hundred GB to several TB. How about using G1GC and Shenandoah properly?
CMS has been deprecated since Java 9 and will be removed in the future JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
Also, I thought that Epsilon GC would be good if it starts with each request like serverless, but when I tried using Epsilon GC with a simple program, it was slow.
230: Microbenchmark Suite There is a benchmark framework called JMH (Java Microbenchmark Harness?), But it seems that it is now included in the JDK. To synchronize maintenance? OpenJDK: jmh
However, I haven't been able to find any material on what has changed compared to using an external jmh and how to use it.
334: JVM Constants API
Dynamic Class-File Constants is included in Java11, and InvokeDynamic can be used for the processing at the time of class initialization. JEP 309: Dynamic Class-File Constants However, no language specification or API was added at this time, so I had to create a class file myself to use it.
The java.lang.constant
package has been added, including the Constable
interface and the ConstantDesc
interface.
And classes such as String
, ʻInteger,
Class, and ʻEnum
that don't use as constants implement Constable
and implement the describeConstable ()
method.
346: Promptly Return Unused Committed Memory from G1 Return unused memory when idle. Reflection of changes in Shenandoah to G1GC.
344: Abortable Mixed Collections for G1
Make Mixed GC stoptable. I don't know if this comes from Shenandoah.
340: One AArch64 Port, Not Two Since there were two source codes of arm64 and aarch64 as Port for ARM64bit, it seems that arm64 was deleted to eliminate duplication of work.
API The API changes aren't flashy either, and it feels like there are some minor fixes.
CompactNumberFormat
It is a NumberFormat
that expresses a large number, for example, 10,000 as 10,000 or 10K.
[JDK-8188147] Compact Number Formatting support - Java Bug System
The instance is obtained by the getCompactNumberInstance
method of java.text.NumberFormat
.
In the case of Japanese locale, it looks like this. It seems that Kyo is not compatible with up to trillions.
jshell> import java.text.*
jshell> var cnf = NumberFormat.getCompactNumberInstance()
cnf ==> java.text.CompactNumberFormat@73cf7357
jshell> cnf.format(10000)
$4 ==> "10 000"
jshell> cnf.format(10000_0000)
$5 ==> "One hundred million"
jshell> cnf.format(10000_0000_0000L)
$6 ==> "1 trillion"
jshell> cnf.format(10000_0000_0000_0000L)
$7 ==> "10000 trillion"
If you specify a locale, you must also specify a style. You can choose either SHORT
or LONG
.
It looks like this with SHORT
.
jshell> cnf = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT)
cnf ==> java.text.CompactNumberFormat@952071d5
jshell> cnf.format(1000)
$9 ==> "1K"
jshell> cnf.format(1000_000)
$10 ==> "1M"
jshell> cnf.format(1000_000_000)
$11 ==> "1B"
jshell> cnf.format(1000_000_000_000L)
$12 ==> "1T"
jshell> cnf.format(1000_000_000_000_000L)
$13 ==> "1000T"
It supports up to T. Isn't that 1 billion 1G? It's like that.
Let's specify LONG
.
jshell> cnf = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.LONG)
cnf ==> java.text.CompactNumberFormat@38c39d6b
jshell> cnf.format(1000)
$15 ==> "1 thousand"
jshell> cnf.format(1000000)
$16 ==> "1 million"
jshell> cnf.format(1000000000)
$17 ==> "1 billion"
jshell> cnf.format(1000000000000L)
$18 ==> "1 trillion"
jshell> cnf.format(1000000000000000L)
$19 ==> "1000 trillion"
In the case of 1000, it seems that it was Kilo's K, but M and T seemed to be Million and Trillion instead of Mega and Tera.
If you want to display after the decimal point, use setMaximumFractionDigit
or setMinimumFractionDigit
.
By default, the numbers after the decimal point are rounded off.
jshell> cnf.format(123456)
$20 ==> "123 thousand"
You can use setMaximumFractionDigits
to specify the maximum number of decimal places.
jshell> cnf.setMaximumFractionDigits(2)
jshell> cnf.format(123456)
$21 ==> "123.46 thousand"
jshell> cnf.format(123400)
$22 ==> "123.4 thousand"
You can use setMinimumFractionDigits
to specify the minimum number of decimal places.
jshell> cnf.setMinimumFractionDigits(2)
jshell> cnf.format(123400)
$23 ==> "123.40 thousand"
String.indent(int) Adds indentation for the specified number of characters.
jshell> "123\n456".indent(2)
$24 ==> " 123\n 456\n"
You can reduce the indentation by specifying a negative value.
jshell> " 123\n 123".indent(-2)
$25 ==> "123\n123\n"
It's a remnant of Raw String Literals. [JDK-8200435] String::align, String::indent - Java Bug System
The ʻalign ()` that was also entered for RSL remains in ea27, but it should disappear in ea28 because there was a delete commit. [JDK-8215490] Remove String::align - Java Bug System
String.transform(Function<String, R>)
This is also a remnant of Raw String Literals.
It applies when there is a function that takes a String
and returns something.
However, with this alone, I feel that I should just call the function normally, but as a motivation, I feel that I can write in the order I think.
[JDK-8203703] String::transform - Java Bug System
For example, suppose you have a function that gives you an address by passing a name, and a function that gives you the population by passing an address. Here is Map.
jshell> var addresses = Map.of("Mike", "Fukuoka", "John", "Tokyo")
addresses ==> {John=Tokyo, Mike=Fukuoka}
jshell> var population = Map.of("Tokyo", 30000000, "Fukuoka", 2000000)
population ==> {Fukuoka=2000000, Tokyo=30000000}
And when I said, "I want to display the population of the person's address when I pass the name," I had to write something like this.
jshell> population.get(addresses.get(name))
$37 ==> 2000000
Although it is a process of "taking a name and taking an address to take the population", it is necessary to write in the order of "passing the name to pass the address to return the population".
This can be written as follows using transform
.
jshell> name.transform(addresses::get).transform(population::get)
$38 ==> 2000000
The order is "take the address by name and take the population".
There are many languages that allow you to write function (value)
in the order of value → function
in the language specifications, but for the time being, it seems that Java has realized that.
I wish I could write in Java in the order of name → address :: get → population :: get
.
Collectors.teeing(Collector, Collector, BiFunction) Connect the results of the two Collectors. [JDK-8209685] Create Collector which merges results of two other collectors - Java Bug System
For example, if you have a list of strings and you want to omit empty strings and separate them with commas to get the final number of elements, you couldn't solve it with a single Stream process, but now you can do that. I will.
jshell> Stream.of("aaa", "", "bbb", "ccc").
...> filter(Predicate.not(String::isEmpty)).
...> collect(Collectors.teeing(
...> Collectors.joining(","),
...> Collectors.counting(),
...> Map::entry))
$39 ==> aaa,bbb,ccc=3
Files.mismatch(Path, Path) Returns the first of the two files in a different position. -1 for the same file I have ʻisSameFile`, but don't you want something different? It seems that it was added. [JDK-8202302](fs) New Files.mismatch method for comparing files - Java Bug System
InputStream.skipNBytes(long) Skips the specified number of bytes and data. [JDK-8214072] InputStream.skipNBytes(long k) to skip exactly k bytes - Java Bug System
I feel that there is a skip (long)
, but skip
returns the number actually advanced, while skipNBytes
does not return a return value and specifies a value beyond the end of the stream. Then it throws ʻEOFException`.
jshell> var input = new ByteArrayInputStream(new byte[5])
input ==> java.io.ByteArrayInputStream@64bf3bbf
jshell> input.skip(2)
$25 ==> 2
jshell> input.skip(4)
$26 ==> 3
jshell> input.reset()
jshell> input.skipNBytes(2)
jshell> input.skipNBytes(4)
|Exception java.io.EOFException
| at InputStream.skipNBytes (InputStream.java:600)
| at (#29:1)
CompletableFuture.exceptionallyAsync(Function)
The methods ʻexceptionallyAsync, ʻexceptionallyCompose
, and ʻexceptionallyComposeAsync have been added to
CompletableFutureto handle exceptions. Actually, it was added to the
CompletableStage` interface, so I implemented it.
[JDK-8211010] Add exception handling methods to CompletionStage and CompletableFuture - Java Bug System
There is already ʻexceptionally`, but compose and async versions have been added.
System changes that I can do. This kind of refactoring is often included. [JDK-8214971] Replace use of string.equals("") with isEmpty() - Java Bug System
The jfr command has been added.
$ jfr print --categories GC --events CPULoad recording.jfr
It seems to be used as [JDK-8205517] JFR tool - Java Bug System
Recommended Posts