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` 🏃🏾
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.
That's a guiding light of #ProjectAmber and record serialization is the first step. The Inside Java Podcast episode on that topic with Julia Boes and @chegar999 (inside.java/2021/03/08/pod…) gives great insight into how it achieves that. 🧵
1/10
First, what's wrong with regular serialization? In short:
* extralinguistic mechanism (aka "magic")
* undermines encapsulation
* causes security issues
* hinders evolving code
* holds back new Java features
In long (and why it turned out that way), see attached thread.
Do you dream of "value types" in Java? So do I! Hence I was thrilled to see that Project Valhalla is slowly coming out of exploration with two draft JEPs.
Here's what they currently propose. 🧵👇🏾
(If you prefer video: https:/www.youtube.com/watch?v=WBvTilbh8S0&t=344s)
1/10
First, why value types? To bridge the divide between
* primitives (fast, no memory overhead) and
* reference types (abstraction, safety, identity)
As is, we sometimes have to choose between performance and design. And we often choose wrongly.
"When people ask me what feature do I most regret, serialization is the easy answer" - @BrianGoetz
Let's talk about serialization in Java: Why does it exist? What are the problems (even today)? Would Java have been better off without it? Can it be fixed?
1/11
NB: What follows is mostly quotes or paraphrasing from a conversation I had with Brian during my 25-hour live stream. If you want to watch the full discussion about serialization, nullability, primitives, and more, you can find it here:
2/11
Serialization was introduced because turning an object graph into bytes is valuable: You can store things on disk, in databases, or send them over the wire. But while the concept is sound, it was implemented in a horrible way.
Project Amber is making progress on pattern matching in #JavaNext. Here are three recent developments that I'm very excited about and I think you will be as well.
(Caveats: these are ongoing discussions; none of this is final; speculation and strawman syntax ahead)
1. "Array patterns" allow matching and destructuring arrays. The `if`-line does three things:
a) is `objects` a `String` array with length 2?
b) if so, cast it to `String[]` and extract the two elements
c) declare `a` and `b` and assign the two elements to them
"Can I also bind the arrays as a whole?"
Likely. This is called an "as pattern".
"What if the array can have more elements?"
Allowing to express "at least two elements" is being considered - for example with three dots.
Yesterday evening, we spent about two hours digging through the German #Corona app and I'm thoroughly impressed. This is a modern project, developed out there as free software (APL 2.0) on GitHub, and it has stellar documentation.
Android and iOS apps use Google's/Apple's Exposure Notification Framework (ENF; google.com/covid19/exposu…, apple.com/covid19/contac…). Android app is written in Kotlin, iOS app in Swift. (Can't tell you much more because I'm clueless about mobile.)