My overview article Java for C# Programmers has been updated for Java SE 8. You can find many links to the new features in the announcement and follow-up post at Oracle’s Java Tutorials Blog. I also once again recommend Cay S. Horstmann’s book, Java SE 8 for the Really Impatient. That said, here’s a quick rundown of the new features I incorporated into my article:
- Unsigned arithmetic is finally part of the standard library, although there are still no corresponding primitive types.
- Static & default methods on interfaces remove a big weakness of the single-inheritance paradigm. Unlike C# extension methods, they package default implementations with the interface itself. Moreover, default methods allow extending an interface without breaking existing clients.
- Lambda expressions are syntactic sugar for function objects, i.e. anonymous inner classes that implement single-method interfaces. That sugar is pretty sweet, though: expressions and parameters are implicitly typed, and you can use method references if you’re just calling one existing method anyway. You get the C#
delegate
functionality for free, too, since every lambda expression or method reference can be stored in a variable typed to a matching functional interface. - Streams & pipelines use lambda expressions to manipulate collection elements, including files or generated data. More importantly, they allow on-demand fetching of new elements and optional automatic parallelization of each pipeline stage.
There were a couple of other noteworthy updates beyond the scope of my language comparison. WebView
got new HTML5 features, and JavaScript outside of WebView
now runs on Nashorn. Java also got better concurrency support, a sane Date-Time API, and built-in Base64 encoding.
2014-04-10: Edwin Dalorzo’s excellent article explains why Java’s predefined functional interfaces are few and messy compared to .NET’s delegate library. The culprits are (as usual) type-erasing generics and lack of value types. Checked exceptions also clash with lambdas: any method that throws them requires another wrapper to get rid of them.