Posts

Looking into Java's Future: Empty Value Types

Although the promising Java value types are not imminent, I still enjoy nosing around occasionally in the OpenJDK valhalla-dev mailing list to see how things appear to be progressing and to get an idea of what is to come. Admittedly, there are some discussions that are beyond my understanding given my limited exposure to the terms used and the low-level specifics of some of these messages. However, there are occasionally messages and threads that I understand well what is being written and find interesting. A recent example of this is the " Empty value type ? " thread. Rémi Forax starts the thread by asking "Is empty value type targeted for LW1 ?" The example error message included with that question shows a LinkageError and ClassFormatError with the message "Value Types do not support zero instance size yet". The response to this question from Tobias Hartmann answers, "No, empty value types are not planned to be supported for LW1 ." Befor...

Deferred Execution with Java's Consumer

In an earlier blog post (" Deferred Execution with Java's Supplier ") I referenced Cay Horstmann 's statement in the book " Java SE8 for the Really Impatient " regarding lambda expressions, "The point of all lambdas is deferred execution ." Horstmann wrote an article called " Lambda Expressions in Java 8 " for Dr. Dobb's magazine in its final year in which he wrote a similar statement using different terminology, "A lambda expression is a block of code that you can pass around so it can be executed later, just once or multiple times." In that earlier post , I looked at how the standard functional interface Supplier is used with lambda expressions in the JDK to support deferred execution for cases where a single value is "supplied only when necessary" and without any argument passed to it. In this post, I focus on JDK-provided examples of using the Consumer standard functional interface to "consume" ...

Java's Ternary is Tricky with Autoboxing/Unboxing

The comments section of the DZone-syndicated version of my post " JDK 8 Versus JDK 10: Ternary/Unboxing Difference " had an interesting discussion regarding the "why" of the "fix" for how Java handles autoboxing/unboxing in conjunction with use of the ternary operator (AKA " conditional operator "). This post expands on that discussion with a few more details. One of the points made in the discussion is that the logic for how primitives and reference types are handled in a ternary operator when autoboxing or unboxing is required can be less than intuitive. For compelling evidence of this, one only needs to look at the number of bugs written for perceived problems with Java's conditional operator's behavior when autoboxing and unboxing are involved: JDK-6211553 : Unboxing in conditional operator might cause null pointer exception The "EVALUATION" section states, "This is not a bug." It then explains that the obs...

JDK 11: Beginning of the End for Java Serialization?

In the blog post " Using Google's Protocol Buffers with Java ," I quoted Josh Bloch's Third Edition of Effective Java , in which he wrote, "There is no reason to use Java serialization in any new system you write." Bloch recommends using "cross-platform structured-data representations" instead of Java's deserialization. The proposed JDK 11 API documentation will include a much stronger statement about use of Java deserialization and this is briefly covered in this post. The second draft of the " Java SE 11 (18.9) ( JSR 384 )" specification includes an "A2 Annex" called " API Specification differences " that includes the changes coming to the Javadoc-based documentation for package java.io . The new java.io package documentation will include this high-level warning comment: Warning: Deserialization of untrusted data is inherently dangerous and should be avoided. Untrusted data should be carefully validated acc...

JDK 8 BigInteger Exact Narrowing Conversion Methods

In the blog post " Exact Conversion of Long to Int in Java ," I discussed using Math.toIntExact(Long) to exactly convert a Long to an int or else throw an ArithmeticException if this narrowing conversion is not possible. That method was introduced with JDK 8 , which also introduced similar narrowing conversion methods to the BigInteger class. Those BigInteger methods are the topic of this post. BigInteger had four new "exact" methods added to it in JDK 8: byteValueExact() - Converts BigInteger value exactly to byte if possible shortValueExact() - Converts BigInteger value to short if possible intValueExact() - Converts BigInteger value exactly to int if possible longValueExact() - Converts BigInteger value exactly to long if possible As described above, each of these four "exact" methods added to BigInteger with JDK 8 allow for the BigInteger 's value to be narrowed to the data type in the method name, if that is possible. Because...

JDK 8 Versus JDK 10: Ternary/Unboxing Difference

A recent Nicolai Parlog ( @nipafx ) tweet caught my attention because it referenced an interesting StackOverflow discussion on a changed behavior between JDK 8 and JDK 10 and asked "Why?" The issue cited on the StackOverflow thread by SerCe ultimately came down to the implementation being changed between JDK 8 and JDK 10 to correctly implement the Java Language Specification. The following code listing is (very slightly) adapted from the original example provided by SerCe on the StackOverflow thread. Adapted Example That Behaves Differently in JDK 10 Versus JDK 8 public static void demoSerCeExample() { try { final Double doubleValue = false ? 1.0 : new HashMap<String, Double>().get("1"); out.println("Double Value: " + doubleValue); } catch (Exception exception) { out.println("ERROR in 'demoSerCeExample': " + exception); } } When the above code is compiled and executed with JDK 8, it g...

Exact Conversion of Long to Int in Java

With all the shiny things ( lambda expressions , streams , Optional , the new Date/Time API , etc.) to distract my attention that came with JDK 8 , I did not pay much attention to the addition of the method Math.toIntExact() . However, this small addition can be pretty useful in its own right. The Javadoc documentation for Math.toIntExact​(long) states, "Returns the value of the long argument; throwing an exception if the value overflows an int ." This is particularly useful in situations where one is given or already has a Long and needs to call an API that expects an int . It's best, of course, if the APIs could be changed to use the same datatype, but sometimes this is out of one's control. When one needs to force a Long into an int there is potential for integer overflow because the numeric value of the Long may have a greater magnitude than the int can accurately represent. If one is told that a given Long will never be larger than what an int can ho...