
Everything about Java 8 - mhixson
http://www.techempower.com/blog/2013/03/26/everything-about-java-8/
======
bhauer
I'm excited by Java 8 moreso than at least several of the previous versions.
Java 7 was especially underwhelming.

The lambdas are the new hotness that everyone is aware of. But the work done
on streams is almost equally impressive.

There are several other small additions and reductions in pain that, when
taken as a whole, make this update significant. For example, we finally will
have a native JodaTime-like replacement for Calendar, Date, and the supporting
utilities. I've long considered the need to enforce external thread safety on
DateFormatters to be one of the silliest design failures in Java.

Disclosure: this summary was written by a colleague of mine.

~~~
lmfao
I am hacking a while now with java 8 and can say that one of the most
appreciated features in my stack are lambdas. as soon as you are used to them
(had the first introduction to lambda-style programming with Blocks in ObjC)
you miss them so badly when they are not there (C for example).

------
gjulianm
As a C# developer now experimenting with Java, I still miss some things even
from Java 8. Probably some have technical reasons behind, but...

\- Getters and setters, C# style. That is, instead of

    
    
        private int foo;
        public int getFoo() { return foo; }
        public void setFoo(int value) { foo = value; }
    

write this:

    
    
       public int Foo { get; set; }
    

which is both easier to write and makes code more readable and understandable.

\- Mandatory exception declarations in methods. I still don't understand why
this is necessary. It ends up either leading to stupid errors (see the
following example from the article)

    
    
        void appendAll(Iterable<String> values, Appendable out)
                throws IOException { // doesn't help with the error
            values.forEach(s -> {
                out.append(s); // error: can't throw IOException here
                           // Consumer.accept(T) doesn't allow it
            });
        }
    

, or to lots of methods just throwing Exception (bad practice, I know, but
it's easy to fall in), or to useless empty try-catch on methods that won't
throw an exception (because you've checked it) and don't want to add the throw
declaration.

\- Modifying external variables in a lambda expression. Just as everyone is
used to in Javascript, Ruby, C#... It's pretty useful, even more when you're
using lamdbas for common operations such as _forEach_.

\- Operator overloading. When you're using data classes (for example, models
from a database) where different instances actually point to the same object,
overriding == it's more comfortable than _foo.equals(bar)_. Also, the downside
of using _.equals_ is that, if _foo_ is null, you will end up with a nice
NullPointerException out of nowhere.

\- Events! I'm amazed how easy is to do events in C# versus how hard (and
bloated) in Java. Take this as an example:
[http://scatteredcode.wordpress.com/2011/11/24/from-c-to-
java...](http://scatteredcode.wordpress.com/2011/11/24/from-c-to-java-events/)

\- Pass by reference. Just as if you were passing a pointer in C. I find it
surprising how few languages implement this feature, which is pretty useful...

And I'm sure I'm missing something...

Edit: added three bullet points.

~~~
Hermel
I don't think there are technical reasons behind, but rather philosophical
ones.

\- Getters and setters are bad design. In clean object-oriented code, the
internal state of a class is not exposed to the outside. Thus, getters and
setters should not be encouraged.

\- Exceptions: yes, it would be nice to be able to throw checked exceptions in
that example. But the rule that they need to be declared is one of the basic
design decisions Java has taken with the intention of always forcing the
programmer to handle them. It won't change. (You can still fall back to
unchecked exceptions if necessary.)

\- Modifying external variables: can be done with a work-around, e.g. "final
int[] x" to have a modifiable int. Not sure why that is the case though.

\- Operator overloading: considered bad practice for high-reliability code.
Generally, Java favors explicit statements in order to prevent mistakes.

\- Events: some of the listener stuff in the example could be moved to a
library, making it smaller. But still a missing feature in Java.

\- Pass by reference: this is normally used as a workaround to create methods
with multiple return values. In Java, one could again use the wrapping-array-
workaround instead as in the external variables point. I'd love to be have
methods with multiple return values in Java.

~~~
Chris_Newton
_Operator overloading: considered bad practice for high-reliability code.
Generally, Java favors explicit statements in order to prevent mistakes._

Considered by whom?

The example gjulianm gave, where == is safe if nulls are flying around but
calling .equals() on a null expression results in an exception, seems a clear
counterexample.

I’d also argue that if your code is mathematical in nature, it is both quicker
and more reliable to write, review, and maintain concise, mathematically
natural syntax like a+b*c than verbose alternatives like a.add(b.multiply(c)).

~~~
amouat
Considered by people who have used C++ and seen some awful problems creep in
because of unnecessary operator overloading.

Your last point actually highlights the problem - it is _not_ more reliable
because you are assuming what "+" and "*" do.

EDIT: An old blog post about the issue:
[http://cafe.elharo.com/programming/operator-overloading-
cons...](http://cafe.elharo.com/programming/operator-overloading-considered-
harmful/)

~~~
Chris_Newton
_Your last point actually highlights the problem - it is not more reliable
because you are assuming what "+" and "_ " do.*

How is that any different to assuming what add() and multiply() do?

In many ways, I’d say the latter is worse, because it’s not immediately
obvious from just the function names whether the operation mutates the object
it’s called on or returns a new object with the result while the originals
remain unchanged. Both behaviours can be useful. Both are widely used in
libraries, with those exact function names. You just have to read the
documentation and learn how each library you use works, which is
particularly... entertaining... if your project uses multiple libraries and
they don’t all follow the same convention.

For + and * operators, someone already decided what the convention should be.
If you just make them work like the built-in versions, the semantics are
already intuitive to anyone who studied basic arithmetic at school.

Edit: I did take a look at the article you cited. It appears to be an
elaborate troll, actually consisting of little more than a set of unlikely
examples (I wouldn’t write a function called divide() to “divide” two
matrices, so why would I suddenly feel the urge to write a / operator?), a set
of assertions without proof (some of which are just begging the question), and
a final _ad hominem_ that conveniently discards one of the most obvious
demonstrations that operator overloading can be useful on the basis that
anyone making that argument just doesn’t understand (and ignores
counterexamples like OCaml, where basic arithmetic operators really are
different for basic numerical types, which is a significant pain point in the
language).

~~~
amouat
> For + and * operators, someone already decided what the convention should
> be. If you just make them work like the built-in versions, the semantics are
> already intuitive to anyone who studied basic arithmetic at school.

I think it's exactly this that is misleading - your intuition may not be the
same as developers. I think people assume more from "+" than they would from
"plus()" and if you don't think about it you may falsely assume you are using
a language built-in.

I'm not saying that operator overloading can't be useful, but in C++
developers did create horrible code by using /, *, + in their classes to 1)
show off that they could and 2) to save typing. If they had to name their
methods, I hope there is a good chance they would have done better than
divide(), multiply() etc.

Regarding the article, I agree it is somewhat guilty of hyperbole, but I don't
think calling it a troll is remotely fair.

BTW I don't understand what you mean by "can be useful on the basis that
anyone making that argument just doesn’t understand", which makes me feel like
I've wandered into a double joke ;)

~~~
Chris_Newton
Fair enough, perhaps calling the article a troll was a little harsh, as I
don’t know how the author intended to come across. However, the article did
seem to consist of one weak argument after another: an unlikely strawman
problem here, a blatant exaggeration there, a quick logical fallacy to tie
them all together. I’m afraid I didn’t find it a convincing case at all.

BTW, I meant my final comment to be parsed as (conveniently discards one of
the most obvious demonstrations that operator overloading can be useful) (on
the basis that anyone making that argument just doesn’t understand). The
author didn’t actually explain _why_ that case was “completely different” or
_what_ someone who proposed that example didn’t understand so that “their
opinions can be discounted”.

In fact, I would suggest that his entire case about built-in operators being
unambiguous even though they support multiple types can be annihilated using
only the equality operator and the words “floating point”: in C, you still
can’t tell whether the expression a==b is reasonable or almost certainly a bug
without knowing the types of a and b, which AFAICS is _exactly_ analogous to
the problem the author is so keen to attack with operator overloading.

------
spartango
Woah, that streaming abstraction looks really slick, especially given that it
can be automatically parallelized.

The idea of doing a one-line parallel map-reduce that is

    
    
        collection.stream().parallel().map(operation1).reduce(operation2); 
    

is surprisingly cool imo. And the availability of streams across the
collections framework allows that they can be used in routine programming.

~~~
eranation
Yep, Java 8 starts to look a lot like Scala

~~~
727374
It looks like C# 3 (2007)

~~~
trailfox
Many C# features look a lot like Scala features (2003/4)

------
RyanZAG
Massive issue here for many when it comes to Java 8 - what about Android ?

Android's dalvik is based off of Apache Harmony, which doesn't appear to be
updating anymore. Does this mean no Java 8 for Android/Dalvik? Seems like it
would be a major issue if so.

~~~
pjmlp
Google is yet to even add support for the Java 7 language constructs.

------
j-m-o
As a daytime Java developer who dabbles in Scala on the side, these changes
look great. The inclusion of a Joda Time style time library is long overdue as
well.

I just wonder how many years before there's adoption from the general Java
community.

~~~
trailfox
As a daytime Scala developer who seldom uses Java anymore these changes are
nice, but a far cry from what I get in Scala.

~~~
djhworld
The Scala compiler takes so long in comparison to javac though

~~~
trailfox
Javac also takes longer than Turbo Pascal to compile...

------
scanr
Java 8 looks good enough to make Java a reasonable candidate for Java.Next.
Especially given that there doesn't appear to be a clear winner between the
alternatives (Scala, Groovy, Clojure, Kotlin etc.).

Java 8 seems to have borrowed a lot from Guava (Optional, Function, Predicate,
Supplier etc.).

Extension methods as well as default methods on interfaces would have been
nice.

~~~
swift
Mixins would be great too.

~~~
tomjen3
Default methods in interfaces makes them mixins.

------
zmmmmm
These changes are the first since Java5 to make a real difference to how I
will program, and thus are pretty nice to see.

The sad thing is that a large part of my Java programming will involve
Android, and thus I will continue living in Java5/6 land, as will numerous
libraries and large parts of the Java ecosystem.

I wonder when Google will address the future of Java on Android in a
substantial way? Eventually it will not be tenable to stay on a 10 year old
version of a language. I hope they will seriously consider either updating
their supported syntax to be compatible with Java8 or introducing some other
language into the Android SDK (Go go!).

~~~
PySlice
I remember some years ago when I was glad Java 5 had got some really practical
new features. I didn't program in Java back then, but I wanted the language to
evolve (maybe I was going to need it in the future).

Now I do program in Java 5/6 and it would be really sad if the language was
still stuck in the 1.4 days.

------
peeters
The lambda and stream additions are great and long overdue, but I've pretty
much adapted to using Guava to fill that gap.

So right now the thing I'm most interested in is actually the promise of
better type inference. Anyone who has used a rich, type safe DSL like Hamcrest
or Guava knows the pain of having to give so many type hints to the compiler,
when the context provides all that the compiler should need.

------
thecombjelly
The inclusion of lambdas is great, but not supporting full closures severely
hampers their usefulness. Instead of using lambdas to use patterns like CPS
(continuation passing style) or alternative object interfaces, lambdas just
save you from typing extra characters.

It is always fun to watch other languages continue to implement features that
bring them closer to lisp. I wonder how much longer it will be until every
language is just a lisp dialect.

They are moving in the right direction but very slowly. It is impressive
though that they have been able to still innovate without breaking backwards
compatibility.

~~~
nollidge
> It is impressive though that they have been able to still innovate without
> breaking backwards compatibility.

Indeed. The .NET IL compiler actually supports closures by generating a class
with the lambda's method body as method on that class. That method takes in as
parameters whatever outside variables need to be captured.

It also supports iterator continuations (e.g. "yield return") by generating an
entire class which inherits off of IEnumerable and wraps your single function
with all the necessary trappings to track the continuation state.

You can see this stuff by looking at C# assemblies in a free program called
ILSpy[0]. Normally it'll reverse-engineer these compiler patterns, but if you
uncheck all the "decompile" checkboxes in the options, it'll just straight-up
translate the IL to C# and you can see the dirty tricks.

[0] <http://ilspy.net/>

~~~
thecombjelly
C# is quite impressive, especially in comparison to Java. If it had been
released earlier, wasn't owned solely by Microsoft, and supported all major
platforms equally, it could have been huge, even larger than Java. If C# had
reversed roles with Java a significant portion of the world would have been
more productive.

~~~
trailfox
C# 1.0 was very close to being an exact copy of Java. To say that if C# had
been released before Java it would have been more popular is nonsensical as it
started life as copy-cat Java. Without Java there wouldn't be a C#. Later
versions of C# added more features much faster than Java. Many Java developers
have since moved on to Scala and other JVM languages which are more expressive
than C#.

------
DoubleMalt
Can someone please show the java guys the <Number>.TryParse(String s) from C#?

I'm convinced everytime I have to manually write the try catch clause for
parse a kitten dies somewhere!

~~~
MichaelGG
TryParse uses an out parameter. Java doesn't have that. AFAIK, the JVM has no
way to represent pointers in any such fashion.

It's sort of ironic that the JVM, with it's limited Java-only bytecode has
attracted so many languages, while the CLR, which is designed to handle
multiple languages in an efficient manner, has relatively few.

~~~
ScottBurson
I started to reply that Microsoft could fix that by providing high-performance
CLR implementations on all the platforms the JVM runs on.

But it occurred to me that even if they did so, a lot of people wouldn't trust
them to continue to support the other platforms indefinitely. The only way
around that would be for them to spin off the entire .NET division.

Microsoft being Microsoft, of course, they would never do any of this.

------
krg
This looks very thorough. I appreciate the detailed coverage of lambdas as
well-- this is already helping my understanding.

------
stack0v3erfl0w
I recently started developing in Java and the thing I find most irritating is
the lack of operators overload.

~~~
pcote
Why? Sure, overloading a "+" operator can be elegant looking. But the
aesthetic gain vs. maintainability doesn't seem to be worth the tradeoff 99%
of the time. I certainly wouldn't want to be the one who has to debug the
thing because someone accidentally side effected one of the "operands".

~~~
stelonix
Nonsense. To paraphrase myself from a similar discussion on reddit:

"List.add(otherList) <\-- what does this do? Why, compared to operators, would
a function name be any better than an operator? Mathematics are part of
computer science, and denying basic operators for a reason like "because
someone might misuse them" is like denying functions because someone may
implement a sum() and call it lcm() (and then we're back to goto land). You're
confusing a programmer's error (bad choice of a name/operator function) with a
language feature. Just because people can write bad code it does not mean we
should disallow them to write great code."

Honestly, it's about time the Java crowd stops with the mantra and starts
thinking from themselves. Or at least, learn why the reason you hate operator
overloading is fallacious.

~~~
smackfu
It just seems an odd hill to die on. Just a minor little feature that most
people would use only occasionally in their objects.

~~~
masklinn
> Just a minor little feature that most people would use only occasionally in
> their objects.

Yeah until you have to work with java's Bignums one day, then you start
wanting to choke people to death.

~~~
PySlice
Yeah, I guess it sucks if you work with Bignums. I would be happy if
BigInteger and BigDecimal were promoted String-level language support: still
implemented as classes, but with compiler support. They could add indexing []
for collections, but I can live with .get() and .put().

Some people seem to think that if they don't use, then it doesn't matter. In
many business applications, you don't even need floating point (you just
transfer data to the database and back), anyway.

Are floats and doubles "little features"?

In computer graphics, you need lots of floating point calculations. Are ints
and longs "little features"?

In embedded software, you usually don't want to use resizable strings (C
doesn't even have this feature built-in), because reallocations are expensive
or unavailable. Are resizable strings (or containers) "little features"?

Different programs have different needs. If you haven't stumbled upon a good
use case, doesn't mean that it's useless.

~~~
smackfu
This same logic can be used to defend any "little feature". Language design is
all about where you draw those lines.

~~~
PySlice
That logic is just a starting point (just to avoid the "I don't need it, why
can't you be just like me?"), not the whole thing.

Then you have to take into account a few other criteria, such as [1] internal
coherence in the language, [2] difficulty in implementation (and explaining to
others) [3] what your target audience is, and what they want, [4] what
competitors are doing.

I think full operator overloading would hurt [2], but special-casing Bignums
would not hurt [1], [2] at all (as I said, JSP EL already have +,-,*,/, etc. ,
String already have +, +=).

[3] This is what this thread is all about, no need to repeat :-D

And [4]... Well in this case Java is really playing catch up.

------
pfalls
Streams, lambdas and the new time API are wonderful additions to Java.

------
simpsond
Java 7 failed to excite me. Java 8 however, has many features that I can use
today. Lot's of stuff from guava, cleaner anonymous classes (lamdas), trait-
like interfaces, FluentIterable++ (streams)... it's a good time to be a java
developer.

------
mark_l_watson
Unless I am mistaking, Java 8 fails to address the major pain-point I have
with Java: hash and array literals.

For me, one of the big wins of both Clojure and Scala is being able to handle
maps, sequences, etc. conveniently.

~~~
quatrevingts
Really? new double[] { 1.0, 2.0 }? Arrays.asList("foo", "bar")? Guava's Map
builders?

Lambdas are what make operations on data structures convenient in Scala and
Clojure, not saving a few characters on the handful of literals in your code.

------
foohbarbaz
I am not sure I am super excited about Java the language increasing in size.
As in, the size of the body of knowledge that need to be committed to one's
head to comprehend and write the code.

I am actually quite opposed to the syntax sugar features like "getters/setters
from C#", "events" and what not. Java the language is already large enough.
IDEs do a decent job dealing with boilerplate code. Please, no new kludgy
additions to the language.

Those people that need functional features could use Scala now. Jython is
there for those not liking static typing.

Why don't we just leave Java alone?

------
miloshadzic
The only thing I wish made it in for 8 was coroutines(MLVM project).

~~~
spullara
I'm definitely pushing for this to be added ASAP — probably won't be before 10
though. In the meantime, it would be awesome if they could get it into OpenJDK
behind a flag...

~~~
karianna
There's no real work being done on this at the moment (I was involved with
trying to kick start a small team with the original patch authors). We've
started discussing it again, but it's looking like a case of "Real Life"
getting in the way :-|. Will see if I can get the broader Adopt OpenJDK
programme to take it on board.

------
jfb
Incomplete lambda forms? Facepalm.

~~~
quatrevingts
Incomplete how exactly?

------
olegp
I find Nashorn particularly interesting, as well as Node.jar: [http://insin-
notes.readthedocs.org/en/latest/JavaOne2012/nas...](http://insin-
notes.readthedocs.org/en/latest/JavaOne2012/nashorn_node_jpa_persistence_bof.html#node-
jar-akhil-arora)

Hopefully Nashorn will give <http://ringojs.org> a boost as well.

------
svdb
One small correction/addition: For Stream.anyMatch(), Stream.findFirst() and
Stream.findAny() it is mentioned that these are short-circuiting operations.
This is however also true for Stream.allMatch() and Stream.noneMatch().

~~~
mhixson
You're right! Thanks, I'll get that fixed up in the next batch of edits.

------
IanDrake
>Non-final variable capture - If a variable is assigned a new value, it can't
be used within a lambda. This code does not compile:

So, it sounds like that mean no closures? That's one of my favorite tools in
c#.

~~~
quatrevingts
Everyone gets confused by this it seems. You can mutate fields in the
enclosing class. You can read locals. If you really want to, you can box a
local, and then mutate it inside the box. You can't mutate locals directly,
because that would make lambdas significantly slower for very little benefit.

(You would not be able to do stack allocation of locals in frames that contain
lambdas (unless you could prove that the lambda does not escape).)

------
smrtinsert
Language and api wise these are nice additions, but all I can think about
these days is emscripten. The JVM should support the client side out of the
box, why oh why didn't Google buy Java?

~~~
krg
I'm not sure what you mean exactly, but as mentioned in the article they've
built a new JavaScript engine (to replace Rhino) to be included in Java8:
<http://openjdk.java.net/jeps/174>

~~~
smrtinsert
Just that an entire revolution is happening in the browser itself, I'd really
like to be able to code Java directly with something GWT. I read recently that
GWT has support for the latest html5 stuff, but complaints about compile time
and lack of performance after compilation turn me off...

~~~
johnyzee
You should give GWT a go. Compile time is a valid complaint, though it can be
mitigated by only producing a single permutation (browser specific output)
while in development, rather than the default five-six. Also note that during
development you usually don't compile but run in "dev mode", a browser plugin
that runs against your actual Java code.

Performance after compilation is certainly not a problem, on the contrary the
GWT output is very tight, especially with full obfuscation (aggressive
optimizations, inlining etc.).

(I've written a complete HTML5 game engine in GWT:
<http://www.webworks.dk/enginetest>)

~~~
dougk16
Another valid complaint is that dev mode runs quite slow, particularly if
you're developing something like a game. I read an article about how they are
addressing this so that dev mode runs almost as fast as the compiled result,
but can't find the link now. Maybe it's already live? Been half a year since
I've used GWT.

But I second the recommendation overall. One thing I learned the hard way
though, is that their widget library is pretty constraining, and a very leaky
abstraction. I would consistently run up against walls using a particular
widget, bang my head against it for a day or two, then scrap everything and
roll my own solution. Eventually, I just used GWT to compile the core business
logic of my app (which would have been a nightmare to do in JS), and did UI
with the standard HTML/CSS/JS flow. Doing UI in Java is too clunky for me no
matter what library I'm using though, so YMMV.

~~~
edwinnathaniel
> Doing UI in Java is too clunky for me no matter what library I'm using
> though, so YMMV.

For sure. C#, Java, C++ are all clunky. Maybe it's the nature of the
ecosystem.

This is one thing I hate about GWT: it offers tons of upside (sprites,
bundles, i18n, unit-test in JUnit IF using MVP) but the downside is in the
area of big-consideration of pain point.

~~~
johnyzee
With GWT it is possible to pretty much build your UI in HTML and simply inject
key components, with event handlers etc., into the DOM structure. You would
use an HTMLPanel and add(Widget widget, String id). Few people seem to be
aware of this.

I used this approach to build TeamPostgreSQL (demo at
<http://teampostgresql.herokuapp.com/>), where the designer built the entire
interface in HTML and I just inject GWT widgets in the right places.

------
davesims
With the ability to add static methods and default implementations to an
interface, what is now the _practical_ difference between that and an abstract
class?

~~~
danieldk
\- A class can only inherit from one abstract class, but can implement
multiple interfaces.

\- An interface cannot have member variables.

~~~
twic
Also, an abstract class can have a constructor (and instance initializers, and
initialization expressions for its fields), which an interface can't. That
means an abstract class can do work when it is created.

Although it's probably a good idea not to do too much work - a factory method
would be better for that.

------
fierarul
Very interesting read. So, nothing new on the Swing side?

~~~
sgt
I can't tell if you are serious or not. Swing is dead, from my point of view.
In any case, desktop programs isn't really a strength of Java.

~~~
tomjen3
Actually that is a case where Java really shines, as it is cross-platform

------
martinced
_"Interfaces can now define static methods. "_

Twenty years for that one ; )

zomg. Another one debated at length through flamewars on Usenet and ##java.
And now it's here. Feeling good : )

~~~
ShabbyDoo
The number of times I've implemented something by convention due to the lack
of this construct... One common use case is that I like "value objects" -- an
AccountId class vs. just a String or an Integer. I usually implement them
using some sort of internment internally -- WeakHashmap, Guava Interner, etc.
When reading from a wire format and using value objects, one must presume the
existence of a fromString(String key), fromInt, etc. method. I'd love to state
explicitly that all ValueObjects have particular, generic-ified static
constructors. Much cleaner. And, it avoids the cliche Java programmer shame of
implementing AbstractValueObjectFactory, etc. Some static state, if isolated
and properly managed, makes life easier.

