From compact record constructors to pattern matching, from generic wildcards to chaining predicates and comparators, from jpackage to jlink - here are 11 #Java tricks handpicked from dev.java. 🧵
(Musical version of this thread: )
0/11
A #record's *canonical* constructor has one arg per component but in its *compact* form, you don't have to list them. You also don't have to (in fact, can't) assign fields, just do the checks/reassignments you need, rest happens automatically.
Serialization works great with #records, no black magic needed! The guaranteed presence of constructor parameters and accessors makes serialization work with the object model and makes it easy to create reliable serializable records.
The command line tool #jpackage takes a whole Java app as input and produces a fully self-contained application image that includes your code, dependencies, and a Java runtime. The cool thing: Unlike jlink, your app doesn't need to be modular!
The #break and #continue statements can be followed by a label. You can use this to stop the execution of an outer loop (with `break`) or skip to its next iteration (with `continue`).
(Usually, other approaches are more readable, though.)
When #pattern#matching, you can use the introduced variables right away to make additional checks by adding `&& $boolean_expression`. This is called a guarded pattern.
* use `and`, `or`, or `negate` to create boolean formulas
* invert a method reference with the static factory `not`
* create an equality check with a specific object by passing it to the static `isEqual`
* to compare objects by an attribute, use `Comparator.comparing`
* to sort by several attributes, chain comparators with `thenComparing`
* reverse with `reversed`
* use `nullsFirst` or `nullsLast` to handle `null`
* create a single source file
* add shebang line `#!/path/to/bin/java --source 17`
* make file executable with `chmod +x`
* rename file and drop `.java` file extension
* run it with `./file-name` 🏃🏾
In two weeks, #Java19 will be released with some of Java's most anticipated features: virtual threads and structured concurrency! 🤩
To make the best use of virtual threads, servers/frameworks need to support them - here's a list of those that do (reply with those I missed). 🧵
📣 All of this is still experimental!
Virtual threads and the new APIs are (you need `--enable-preview` and the incubator module `jdk.incubator.concurrent` to use them) and so is support in these projects. You can help them mature over the next months by testing with your app.
The @JakartaEE server @TheApacheTomcat provided experimental support as a part of their 10.1.0-M16 release back in June, but there was a bug that broke HTTP/2 support if async IO was disabled. The unreleased 10.1.0-M17 will include a fix.
Changes:
* constant case labels must now appear before guarded patterns of the same type
* exhaustiveness checking is now more precise when sealed classes and generics mix
#ProjectLoom's virtual threads will make high performance in concurrent systems attainable with much simpler code. But Loom aims for even more and wants to make the code clearer and more robust by introducing *structured concurrency*.
Here's what that's all about. 🧵
Important: This is about concurrency, not parallelism. See yesterday's thread 👇🏾 for a more detailed distinction, but the gist is that concurrency is about processing lots of tasks that the environment throws at your system at the same time, ideally with high throughput.
* splitting and joining concurrent subtasks in different methods/classes
* little support to compose error-handling, cancellation, … across subtasks
* threading structure is opaque to the runtime, which only sees independent threads
* …
I'm no security expert and don't know how ubiquitous this vulnerability is, but if you use Log4J 2.x, you should probably update to 2.15.x and read these:
Here are 11 improvements you get when updating to #Java16 later today: from records and type patterns to `Stream`-additions and Unix domain sockets, from creating installers to more performance and observability. 🧵👇🏾
Express in a single line that a type is just a collection of data without need for encapsulation and let the compiler do the rest:
record Range(int low, int high) { }
That results in almost the same API as the attached class. *drops mic*
#2 Type Pattern Matching
This is actually two-for-one:
* first step into pattern matching
* type patterns with `instanceof`
With a type pattern you check whether a variable is of a certain type and, if so, create a new variable of that type, so you can use it without casting.