New language features in Java 7
I’m just back from the Devoxx conference in Antwerp. An update was given on the new language changes that will be in Java 7. The JDK currently has a release date of September 2010.
Here are 7 of the new features that have been completed:
- Language support for collections
- Automatic Resource Management
- Improved Type Inference for Generic Instance Creation (diamond)
- Underscores in numeric literals
- Strings in switch
- Binary literals
- Simplified Varargs Method Invocation
There is a lot more to Java 7 then just these language changes. I’ll be exploring the rest of the release in future posts. One of the big debates is currently around Closures, which are a separate JSR.
Language support for collections
Java will be getting first class language support for creating collections. The style change means that collections can be created like they are in Ruby, Perl etc.
Instead of:
List<String> list = new ArrayList<String>();
list.add("item");
String item = list.get(0);
Set<String> set = new HashSet<String>();
set.add("item");
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("key", 1);
int value = map.get("key");
You will be able to use:
List<String> list = ["item"];
String item = list[0];
Set<String> set = {"item"};
Map<String, Integer> map = {"key" : 1};
int value = map["key"];
These collections are immutable.
Automatic Resource Management
Some resources in Java need to be closed manually like InputStream, Writers, Sockets, Sql classes. This language feature allows the try statement itself to declare one of more resources. These resources are scoped to the try block and are closed automatically.
This:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
becomes:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
You can declare more than one resource to close:
try (
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest))
{
// code
}
To support this behaviour all closable classes will be retro-fitted to implement a Closable interface.
Improved Type Inference for Generic Instance Creation (diamond)
This is a particular annoyance which is best served with an example:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
becomes:
Map<String, List<String>> anagrams = new HashMap<>();
This is called the diamond operator: <> which infers the type from the reference declaration.
Underscores in numeric literals
Long numbers are hard to read. You can now split them up using an underscore in ints and longs:
int one_million = 1_000_000;
Strings in switch
Currently you can only use numbers or enums in switch statements. String has been added as a candidate:
String s = ...
switch(s) {
case "quux":
processQuux(s);
// fall-through
case "foo":
case "bar":
processFooOrBar(s);
break;
case "baz":
processBaz(s);
// fall-through
default:
processDefault(s);
break;
}
Binary literals
Java code, due to its C heritage, has traditionally forced programmers to represent numbers in only decimal, octal, or hexadecimal.
As quite a few domains are bit orientated, this restriction can introduce errors. You can now create binary numbers using an 0b prefix.
int binary = 0b1001_1001;
Simplified Varargs Method Invocation
When a programmer tries to invoke a *varargs* (variable arity) method with a non-reifiable varargs type, the compiler currently generates an “unsafe operation” warning. JDK 7 moves the warning from the call site to the method declaration. This will enable API designers to use varargs due to the reduction of warnings reported.
This one is slightly more involved so you are better off looking at the proposal.
Subscribe to the RSS feed and have all new posts delivered straight to you.
In your list and map examples, should you specify the types, as in:
Map map = {”key” : 1};
int value = map["key"];
OK, let’s try this again:
Should it be:
Map<String, Integer> map = {”key” : 1};
int value = map["key"];
wow, that “declare more than one resource” might have been better with this sort of syntax:
try (
InputStream in, OutputStream out = new FileInputStream(src), new FileOutputStream(dest)
){
body
}
that way you could place the tuple inside a function that returned both in, and out.
not that tuple support exists
@Eric Burke
Just re-read Joshua Bloch’s proposal where he has them typed like your example:
http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001193.html
I’ll update the examples to be similar. Cheers for the spot.
@Gordon J Milne
I see your reasoning. However, the classes created that you want to be closable tend to be on the verbose side. For this reason I’d prefer the standard end of line separator.
@Eric Burke
I actually had them in the post already! Like your original comment, I found that Generics aren’t HTML friendly. Fixed now.
You show this for creating a set:
Set set = {”item”)
So you start with a curly-brace and close with a parenthesis?
or should it be parenthesis on both sides, as in:
Set set = (”item”)
Interesting stuff.
In the first example (second listing) is there a mistake?
Set set = {”item”)
should be
Set set = {”item”};
@Craig and @Ari (both were in moderation queue)
It’s curly brackets for Map and Set. Square brackets for List. I’ve updated the post. Cheers for the feedback.
Thanks for the nice post, well done.
Best Regards,
Rick
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
Leak is possible here, if error occurs in BufferedReader constructor (for example, OutOfMemoryError).
where is the clousers???
@Stepan
It’s synthesizing a try{}finally{} and I don’t think people catch exceptions that are of type Error.
@madhu
Separate JSR. I linked to the current state of closures in the post.
Hi Joe,
Thanks for your post. Very informative and well composed.
I’ve got a question… in the following:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
what is the scope of variable br?
Mainly i would like to know if add a finally to the try will it be visible?
cheers,
Rashmi
Good to know that Java is (slowly) catching up to C#
Hopefully switch on Strings, first switches on hashCode, and then differentiates from there.
@MeBigFatGuy
That’s correct. Hashcode then Equals.
Wow finally switch statements support strings. This has been a pet peeve of mine in Java for a while!
They way they did automatic resource management looks a little weird to me. They essentially added special syntax for a very small ‘corner’ of a normally (for better or worse) verbose language. In itself it looks good but looks iffy taken in the context of everything else in Java.
As for language support for collections I wonder if it turns out to be something similar to how they did arrays where you can to do:
f(new int[]{1,2,3});
or:
int[] x = {1,2,3};
f(x);
but not:
f({1,2,3});
I like the improved type inference and strings in switch though.
Why square brackets for list? (given sets and maps also use the curly brackets, which to my understanding, good old arrays also use?
Most other languages use square brackets for list. You can’t create an Array like this:
return [1, 2];
You have to:
return new int[]{1,2};
So there’s no collision there.
@Joe Wright: hashcode then equals
an interesting issue, then, perhaps… Is the hashcode value calculated at compile time for the “case labels”? If so you might run into a javac/java mismatch for the impl of hashCode().
I guess there can be no jump table implementation then, it truely must be if/else/if/else even with hashcodes… bummer.
@Joe Wright
>>Most other languages use square brackets for list. You can’t create an Array like this:
>> return [1, 2];
you should be able to..(now)
These are without a doubt welcome, but I wonder if the closing of resources could have been made a little less verbose…
Joe:
Quick tip, I’m colorblind and the yellow (?) in the code is almost impossible to read. Try something darker.
Sorry about that Matt. It’s the theme I’m using for: http://shjs.sourceforge.net/
I’ll see if I can find a different theme for the highlighter. Are there any dark background ones you’ve found which work well?
The “Automatic Resource Management” syntax is horrible. It should be done more like C#:
using (OutputStream out = new FileInputStream(src)) {
// do stuff here
}
Much more readable, IMO.
Sorry, copy/paste FTW…
Correction:
using (OutputStream out = new FileOutputStream(src)) {
// do stuff here
}
Thanks for your post, a lot of this stuff is kind of available using Google Collections. Automatic Resource Management can be partially achieved using Project Lombok. But still, is good to see the language incorporating those features, so no need for external libs.
I have been using some of these features in C# for a long time… its good to see that Java language will also get these new enhancements.
Why reverse type inference ?
I like pythons with keyword much better
with exp as name {
//name is valid here
}
@Luciano
I do like the builder pattern used in Google collections. We used a similar library in our own code until the Google one was released.
@kevin
Saying ‘using’ makes more sense. But that would introduce a new keyword.
@Tariq
I’ll take using IntelliJ Idea on all platforms over language features constrained to one. We all take tradeoffs
I don’t really like how the collection initialization also means the collections are immutable, because there’s nothing in the following code that makes me think they are (i.e. if I didn’t see the initialization line, or passed it to some other function).
I also don’t like how you have to do something explicit to get Closable behavior. This seems like a hack for putting RAII into Java because nothing gets called when an object goes out of scope. Why didn’t they just make it so Closable gets used when an object goes out of scope? Java already has a concept of scope.
@Josuah
Finalize gets called when the object goes out of scope. It doesn’t happen till GC happens though. You could end up never closing a file writer if you keep a reference to it.
The Collections immutable feature is there because it is verbose to currently make immutable collections. It’s designed by Google who favour that approach.
Joe,
What’s the font that you’re using for your code snippets? It’s excellent.
Regards,
James
Just a note about initializing Maps (and Lists):
you can also do it when instantiating as follows
Map map = new HashMap()
{{
put(”key”, 1);
}};
More verbose, but it’s mutable.
BTW, thanks for the post
The ARM looks weird from a typing point of view. This means that in this statement:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
The compiler has to know that “BufferedReader br = new BufferedReader” is an assignment to a Closable object?
So the compiler depends on a specific interface???
Please correct me if I’m wrong but IMHO a much better option would have been to add call-by-name parameter (see Scala) and let people manage their resources with library calls.
Eric.
Can you do stuff like this…
someMethod( {”e1″, “e2″} );
or are they just for initialization?
@James
I’m using http://shjs.sourceforge.net/ with the DarkBlue theme. According to my font picker it’s Verdana at 12 point.
@jos
I work with Classpaths quite a lot. You can’t get away with making extended classes without sharing them
I think Map map = new HashMap({key : value}) would work (or using putAll). That or they’ll put a Collections.mutable(list) method in.
@Ad
I believe you can use them in that form. I haven’t tried it myself yet.
@Eric
Yes, classes need to implement Closable. Existing classes are being retro-fitted. Ideally you’d have closures to handle the cleanup, while the resource is used within the block ala Ruby.
@Joe Wright
I’ll take using IntelliJ Idea on all platforms over language features constrained to one. We all take tradeoffs
——
That was harsh. He is making a valid point unrelated to an IDE. C# has these features are more. In fact, the way they are being implemented in Java looks forced (hacked even). ie:
Type inference still looks backwards (C-like, first type then variable).
ARM (modifications to try) don’t make it more readable unless the IDE provides a lot of support (color coding, pretty-printing etc).
Numeric literals from PHP are better, these ones dont actually make it faster to write long numbers. A combination of number and international units would be a lot easier (1M for one million, 1B for one billion, etc).
Binary literals and strings in switch statements: about time!
@atirado
Pointing out a major limitation is harsh? Then I guess we must both be guilty then.
I disagree about the type inference. Google suggested that type inference style here, it makes sense from a Java pov given the Generics rules already in place.
Not sure what your on about by not understanding ARM. It looks just like a synchronized block to me. Very simple and Java like.
Who’s billion are you talking about (UK and US differ)? Adding measures to Java would add a lot of bulk. It’s implemented via the JScience library if people need access to them: http://jscience.org/
Strings in switch usually indicate a poor design. Enums should almost always be used in these situations. That’s why I put it down at the bottom.
Anyone here know anything about whether LinkedList is supported?
@Joe Wright
Yeah, that’s why I suggested scope. The compiler knows that scope is. So it wouldn’t be difficult for it to generate byte code that closes a Closable when it leaves scope.
I agree that having that special block as part of the try can be confusing, because it could easily look like part of the code to actually try (which it is, since those could throw exceptions too). I really think it would have been better for everyone if it was just based on scope.
Collections.mutable(list) is horrible. Because it means what you thought was immutable can become mutable inside someone else’s function. If you needed a mutable version of the list you’d make a copy like you can today.
Why didn’t they make it so collections initialized this way are mutable? I don’t see the problem with doing so.
Anyway, it’s clear I haven’t been doing Java in a long time because I mistakenly thought there was an “immutable” class type for collections. Since there isn’t, my statement about it not being obvious that a collection is immutable is stupid.
The rest of the things you listed look useful to me. I do think strings in switches can be abused, but has value as a way to handle string-based input of all kinds. In those cases, you’d have to create a big if/else to map them onto an enum to use in your switch anyway.
This is very win.
Thanks for the post.
I really hope that the resource management applies for JDBC connections, statments, and resultsets. That will clear up a LOT of unnecessary boilerplate code. I wonder if a rollback would automatically happen on a close without a commit when setAutoCommit is false.
Thanks for the post.
@Joe Wright, @Joshua
I agree on the strings on switch statements, I use enums myself as well, however I might have missed the part in which you downplayed the importance of this feature due to design reasons which I agree should be more important.
UK 1B versus US 1B: Shouldn’t that depend on the locale? That way you just set the locale in which a program runs (if you want to tighten it that much) and all units/measures are assumed so they make sense.
On ARM, please notice I didn’t say they’re not understandable. The purpose is clear once you get used to the notation and that’s the point I was trying to make. The intention is not obvious, it makes sense once you see the usage in the ‘body’ of the try block.
On type inference what I don’t like is that type inference here didn’t help readability. As in, it doesn’t look like ‘this is a variable of type T’, it is just saving you having to type the type twice. Hopefully that made sense. Still nice to see there’s some help there.
As for the rest, all in due time
. It’s a marathon not a race.
Wow, It’s smellin like 1999 in here, thank god we Created .Net instead of copying this crap!
You forgot to mention the new dating/time libraries… one of the most important improvements IMO.
I see: Map<String, Integer> map = {”key” : 1};
wouldn’t this make more sense :
Map<String, Integer> map = {”key”, 1};
Since we have ‘,’ between the <> keep it between the {}.
@Josuah
I can see your point. The problem with scope is it may be marked as out of scope, but Java (well the JVM) isn’t designed to call cleanup methods immediately.
Collections.mutable(list) would create a new array, at least in my contrived example, and wouldn’t change the referenced one. Thanks for your thoughts.
@Chris
JDBC connections will be included. If you haven’t already, you should check out JDBCTemplate in Spring. It’s a very concise way of using JDBC.
@atirado
Thanks for your well reasoned reply, I agree with all your comments apart from the number locale one. My customers are global as is my software. The same code runs in New York, London and Hong Kong. I would not like to see any mathematical errors introduced because of the location of the server. Dates are enough pain already for me here.
I think most languages have a NumberFormatter of some kind which handles displaying numbers in the current locale.
@Charlie
I see you are familiar with irony. Try asking Alan Kay how he feels about innovation in current language design.
@paolo
I’m not discussing library changes here as that would take a long time. The libraries are still in flux too. String now has a Join method too.
@Pascal
Comma is used to separate keys already: {key : value, key2 : value2 } I didn’t want to inflate the articles example, but maybe I should have.
Ugly source code colours, but interesting article…
@Dennis
Yeah, I don’t think anyone has invented a source code highlighter for Java 7 yet
AWESOME!!! I’ve been wanting String capabilities for the switch structure in Java since nearly day one… It’s going to be a whole new world!!
> List list = new ArrayList();
> list.add(”item”);
> String item = list.get(0);
You can already (since Java 5) do like this:
List list = Arrays.asList(”item1″, “item2″);
@Mikael Ståldal
I use the Arrays.asList(..) a lot too. If you want it to be immutable you have to put it through a Collections.immutable call as well which gets quite verbose. Thanks for mentioning the Arrays.asList() method.
switch with Strings? bleh.
It will only make more people write bad procedural code. Like VB6.
I think an important idiom will be:
Map map = new HashMap({”Foo”: “Bar”, “Hello”: “World”})
and similar for Lists, Sets.
@Josuah
Variables have scope, but instances do not.
InputStream openStream(String path) {
InputStream myInput = new FileInputStream(path);
readHeader(myInput);
return myInput;
}
myInput will go out of scope, but closing is probably not desired at that point.
@Guillaume
It won’t make people do anything, but it will allow them to use it where it would be better to use than an if/elseif ladder.
Apologies to @Matt and other IE[6|7] users. I’ve fixed the code backgrounds to have the right colour. Should be readable now.
What do you mean C heritage on the binary bits?
C has had 0b110010010 as literals forever?
nice updates. I can do without underscores in my code, just looks ugly to me.
were there any updates to the concurrent packages for collections?
@stacy
I’m just concentrating on the language changes, not library changes. There will still be a lot of library changes before the release, I’ll do a post nearer the time for that.
Can you do:
List<Object> list = ["item"];
or something similar, or will it have to be:
List<? extends Object> list = ["item"];
Just switch to Scala already. Java is imploding anyway
thanks! for the info btw. Very concise and clear
@Johan – harsh statement to make seeing as Scala requires Java VM to run…
ARM is such a fugly syntax and such a fugly idea. I hate it in C#, i hate it in java.
These objects should be closed at GC time, or when going out-of-scope. A new variable qualifier would be much better – variables in any kind of block would be able to use it, and there would be no need to even use a try statement.
The lists and sets syntax looks alot like javascript, and I find it a good addition. The immutable thing seems like a problem at first, but in fact, together with the putAll method it´s really better.
Strings in switch statements is a god send. Parsing text files are such a pain. Of course, you could always create a hashmap associating the incoming text with the enum value and then switch based on it, but that’s a complete waste of time/code/effort. Switching based on string.intern will be just as fast and more readable – forget hashCode for strings.
Of course, switch based on hashCode would be able to switch over any kind of variable… seems tasty.
The diamond… well, why not take it away altogether? A nice addition though.
The other changes are nice. It’s good to see the language evolving. Too bad this ARM thing sounds like a knee-jerk reaction to .Net – which actually grows like a tumor. On the rant side of things, I find extremely annoying that there is no trivial way to plug one InputStream into an OutputStream. The opportunities for JVM optimizations are endless.
Good article, by the way
@Renato
Thanks for sharing your thoughts. The case Strings have their hashcode hardcoded at compile time I believe. That shouldn’t have any performance problems.
The ARM thing was because they weren’t going to introduce closures. Joshua Bloch pointed out that the majority of use cases can be covered by introducing features like ARM.
I’ve not heard of any language which closes objects when they go out of scope. I think they get marked for GC collection and then whenever the GC runs the object is closed/collected. This could be after an amount of time.
is this C#?
Is it posible to write:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
catch (Exception ex){
// other exception handling…
}
If it does, then this syntax is better than “using…”.
same as C#! use “try (){}” to close resource ?
Is this “try” can catch some exceptions ?
the “try” is a bad keywords!
I am curious if every string used as the target in a switch statement would get interned?
I hope the ARM will handle exceptions properly. Namely, chain exceptions and aggregate exceptions, so I can diagnose what happened when things go wrong.
For example, if “in” fails on read, and “in” fails on close() along with “out” failing on close(), I had better get back all three exceptions.
I am immensely happy with the improved type inference: I have stayed with type-free collections to avoid the verbosity of generics.
Hi, this is about “Underscore in numeric literals”, why don’t the underscore be replaced with comma which makes more sense and more human readable. How does underscore make a difference from that of comma?
Hi Joe,
Thanks for your thoughts. I posted some followup (at http://www.lessonsoffailure.com/software/official-java-jumped-shark ) on why Java Jumped the Shark with release 7.
Thanks for the posting new changes in JAVA .
@chanrakanth
In Europe a lot of languages represent numbers differently. In the US and UK it’s like 1,000.00, in France and other European countries it’s 1.000,00
I guess using underscores means you don’t confuse anyone by inventing a new standard.
@Dave Rodenbaugh
Cheers for the reference. I agree that if Closures don’t make it in Java 7 then we’ll always be wishing for the heady heights of the Java 5 release.
I wonder when this will change on AP (College Board).
Really interesting.
list and set syntax sugar and I don’t like it. you can always use:
List l = Arrays.asList(…);
Set s = new Set(Arrays.asList(…));
Map m = new Map() {{
put(”key1″, 1);
put(”key2″, 2);
}};
IDE can help if you still think it is too explicit. Just define few live templates.
Don’t like the new “try” statement. Why they couldn’t introduce some new keyword? Looks really weird…
Making such changes is just a waste of time to satisfy noobs and dynamic language evangelists.
@IvanoBulo
These language features allow for making common thing easier. Your map example does not work if serialization is a concern.
There are no new keyword in Java 7. Not sure why you think ‘try’ is new.
Java is a workman’s language. Expressing the intent of code while still having the feel on Java is a good ideal.
If the serialization is a concern in such case then I think such code smells a little. Although it was just an example of how to minimize the efforts in most cases.
As for the making common things easier it would be wise to put efforts on making class properties so it would automatically generate getters and setters. Or to provide build-in hash, equals and to-string builders (or even include all commons-lang). I’m also looking for easier ways to construct decorators and proxies so I could only implement methods I’m interested in and making other methods behave as a decorated/proxied class.
I’m looking for more compatibility with JavaFX technology so I could bind to existing java beans.
Don’t get me wrong, I’m not against these changes, I’m against putting them in favor of much more important things…
There is a good phrase, in my native language, from the old times – “‘better’ is an enemy of ‘good’”. And I think the existing java syntax is good enough.
@IvanoBulo
Thanks for returning to comment. I liked the Voltaire quote too
Serialization is often used in mutli-tiered apps. If you use an XML convertor it would also need to have the custom Hash on both sides too.
http://projectlombok.org/
You might like Project Lombok. Putting a @Data annotation above the class automatically makes properties/equals/hashcode/constructor/toString at compile time. Only problem for me is that it only has Eclipse IDE support, no IntelliJ.
Great rundown. Strings in switches seems so long in coming.
Collections created with the new language sintax will be inmutable? Why?
I understand those new collections will be useful whenever I can’t use an array, but … the main advantage of lists against arrays, is that lists can be modified and more important: List can grow. Without the possibility of mutating collections, language support for collections is a very uncomplete feature.
I’m not quite sure about “Underscores in numeric literals” will be useful to anybody. What do you think about this?
If the serialization is a concern in such case then I think such code smells a little. Although it was just an example of how to minimize the efforts in most cases.
As for the making common things easier it would be wise to put efforts on making class properties so it would automatically generate getters and setters. Or to provide build-in hash, equals and to-string builders (or even include all commons-lang). I’m also looking for easier ways to construct decorators and proxies so I could only implement methods I’m interested in and making other methods behave as a decorated/proxied class.
I’m looking for more compatibility with JavaFX technology so I could bind to existing java beans.
Don’t get me wrong, I’m not against these changes, I’m against putting them in favor of much more important things…
There is a good phrase, in my native language, from the old times – “‘better’ is an enemy of ‘good’”. And I think the existing java syntax is good enough.
@Bruce
Check out Project Lombok. That solves the getters/setters equals/hashcode problem using annotations at compile time. It’s a lovely piece of kit.