Wednesday Oct 26, 2011

Generics Return Type Trick

I've been using Java generics for almost five years, since about a year after Java 6 was released. There is a generics feature that I've been using for most of that time that it turns out I didn't fully understand. Consider the following:
Surprising Java Generics
public class Surprising {

    public static <A extends Collection<String>> A foo(A input) {
        return input;
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<String>();
        List<String> list = array;
        Collection<String> collection = list;
        ArrayList<String> assignArray;
        List<String> assignList;
        Collection<String> assignCollection;
        assignArray = foo(array);
        assignArray = foo(list);
        assignArray = foo(collection);
        assignList = foo(array);
        assignList = foo(list);        
        assignList = foo(collection);

        assignCollection = foo(array);
        assignCollection = foo(list);        
        assignCollection = foo(collection);

Several lines of this program are rejected by the compiler due to "incompatible type" errors. The incompatible type error occurs because the statement is attempting to assign a less specific type, such as Collection, to a more specific type, such as ArrayList. The compiler is right to complain!

The tricky bit here is that the other assignments all work. Consider the very first assignment, "assignArray = foo(array);". The foo() method is declared as returning the generic type variable A which is declared as A extends Collection<String>. Wait a second, if A only specifies that it extends Collection<String> how is it that we are assigning a result of foo() to assignArray which is more specific than Collection? You shouldn't be able to assign a Collection<String> result to a ArrayList<String> variable.

The answer is that the exact return type of foo() is not determined solely by the declaration of A. Instead, the compiler looks at all the usages of A in the expression and determines a single type for all of the As in the expression. If a single type for A can't be determined then the compiler will also produce an error. Usually though it is more common that one of the parameters isn't an A.

For our assignment statement, "assignArray = foo(array);", the type of A is being determined by the type of the parameter "input". Once the actual type of A for this expression is determined to be "ArrayList<String>" then the return type of foo() is compatible with assignArray.

Not all of the assignments in this program need this magic. Most of them work by virtue that the assignment type is less specific than the return type of foo() for that particular invocation.

This property of how a generic type such as A interpreted in Java is extremely useful. It's very commonly used with collections where the collection you get back from a method is the same type as the collection you pass in. You probably use this all the time and, like me, didn't think about it.

Looking back over my old code where I used generics I found a number of cases where I used two type variables, one for return type and one for a parameter, in cases where, because of this magic, only one type variable was needed. If you have code which has a separate type variable for a return type, check carefully, you may not need it and it may actually be less safe than with one type variable and this trick.

Thursday Oct 06, 2011

JavaOne 2011 : Parallel Data for Java Slides

Despite having a bad cold I made it through my JavaOne presentation on the parallel library extensions that are being developed for Java 8. As I said following one coughing bout "DayQuil--unofficial sponsor of this session". Hopefully it was intelligible and coherent for those who had to listen to my coughing and sniffling throughout.

Here's the slides for the presentation 25066 : Bulk Hauling -- Parallel Data for Java. Session audio may be available on the Java Channel in a few days.

Wednesday Oct 05, 2011

JavaOne 2011 : Collections BOF Slides

The annual JavaOne Collections Birds-of-a-Feather gathering was on Monday night. It was extremely well attended and I hope was useful to everyone who participated. Here are the slides for the presentation part of the session. The audio should be up on the JavaOne site in a few days.

2011 Collections Gathering Slides

My other session "Bulk Hauling : Parallel Data for Java" is on Thursday @ 11 in Hilton Yosemite. It will cover the lambda based parallel extensions to Collections we are building for Java 8. See you there!

Update:I've corrected the broken link to my slides. Slides are also up for the Parallel Data talk.

Thursday Sep 09, 2010

Closed Road No Professional Driver

When they eventually make a TV commercial about Shelley I hope that they include the disclaimer "Closed Road No Professional Driver". It sure is odd to see a car driving with nobody in it. Shelley's simplest driving demonstration already exceeds the James Bond autonomous car gimmick from two movies back.

We've now had three full days of testing at Pike's Peak. The testing is going very well and Shelley is performing flawlessly. Most importantly for me the Java systems have been performing flawlessly. If there's one thing I've learned on this trip is that tuning server VM performance is child's play compared to configuring DGPS repeater systems. It's really fun working on a team project like this with automotive , software, mechanical and control systems engineers and uber-mechanics. (OK to most people this probably reminds them of the "Deep Space Homer" episode--"A mathematician, a different kind of mathematician and a statistician"). The discussions around dinner have been really interesting and not all about autonomous cars.

It's rather exhausting working at 2900m (9500ft) and getting up at 0400 to be on the mountain by 0500 so that we can test the car with the road closed to tourists. Hot coffee is your friend. By mid afternoon everyone is starting to look a little dazed and slow. I've only made one trip to the summit so far (didn't get to try the donuts) and I felt a bit winded just standing there.

Photo of the trunk compartment of Shelley with all of the computers and equipment.

The Java system is the black box behind the two red switches. The red switches do not fire up the BBQ even though that's what they look like.

Team members Paul and Mick examining test data after a successful run.

Saturday Sep 04, 2010

Shelley @ Pikes Peak

Next week Shelley, the Java powered autonomous vehicle being developed by Audi and Stanford, will be visiting Pikes Peak for her first "on-the-mountain" trials. This is not the competitive event where Shelley will be trying to race up the entire mountain as fast as possible. There is still almost a year until the official hill climb event. This set of trials will be to evaluate how Shelley is driving so far and how her systems have come together. Most of the driving will be at low speeds, less than 10 km/h. Some higher speed testing is planned for smaller portions of the 11 mile track.

I will post a couple of updates throughout the week with photos of the team and Shelley in action. Right after we return from Pikes Peak, Marcial Hernandez and I will be doing a presentation S312929 : Java in the Real World: Experiences with Real-Time Java for Device Control at JavaOne 2010. We should have some really great stories and exciting video to share.

My recent contributions to the Shelley project have been to create visualizations for the Java safety system. I won't share the actual UI just yet as it's still in progress, but here's a small tease:

Screenshot of a Java Swing application showing two track views.

This shows two views of the same track. The left shows the entire track, in this case a short track used in testing at Santa Clara County Fairgrounds, and the right track is a magnified view showing only two curves of the same track. The black dot on each view is the position of Shelley on the track. The maps used by Shelley are described as a series of curves. The map is a representation of the path Shelley should travel to traverse the road. Each curve consists of four parts, a straight segment, an entry segment, the curve proper and an exit segment. In this visualization the segments are red, green, blue and cyan respectively. On the magnified view there is a line drawn between Shelley's location and the track.

I will explain more about what's shown in the visualizations in future postings.




« August 2016