torsdag, maj 18, 2006

JavaOne, day 2, first part.

So, this day I've been trying to keep my notes more close to the final result seen in this blog, with the result that I'll actually be able to post information even before the day is over. So, what I'm posting now is information from the beginning of the day, to the JRuby session that ended at 5pm.

Effective Java Reloaded
Effective Java has not been reloaded. Or not yet at least. But there is much material that can be used, and the session went through some great stuff. The presentation were divided into three parts, Object Creation, Generics and Other.

So, the object creation part had some great patterns. The first regarded static factories and how you can use factory methods to improve creation of
generic instances. For example, take this horrible example of creating a HashMap:
Map<String, List<String>> m = new HashMap<String,List<String>>();
Instead, HashMap should have a factory method, and then you can do this:
Map<String, List<String>> m = HashMap.newInstance();
The recommendation is to always write your generic code like this.

There are a few disadvantages that both static factories and constructors share. A big one is optional parameters. There are many ways of solving this, but none good. The pattern to fix this is to use a variation of the builder pattern.
You create a static Builder nested class, this builder constructor takes all required parameters and then provides setters for all optional parameters. It also exposes a build method that returns a created object. An example:
final NutritionFacts twoLdietCoke = new NutritionFacts.Builder("Diet Coke",240,8).sodium(1).build();
or even
final NutritionFacts twoLdietCoke = NutritionFacts.builder("DietCoke",240,8).sodium(1).build();

This approach is really powerful. If we're lucky this interface may be added to the JDK in the future:

public interface Builder<T> {
T build();

Then we could stop passing Class objects around, and use the typesafe Builder instead.

The generic part of the session had some interesting information that was new to me, at least.
The first recommendation was to never use raw types anymore. Those are only for legacy code. Raw types are really evil.
You should never ignore compiler warnings. They should be understood and eliminated if possible. If not they should be commented, and suppressed with the SuppressWarnings annotation if it can be proved safe.

Wildcards should be preferred to explicit type parameters. In many cases this makes method signatures clearer, and you don't have
to manage a type variable. The exception to this is conjunctive types (which is really neat too).

Bounded wildcards are almost always better to use in your API, it will make it work for many more cases where people expect it to work.
The usual case when this is a problem is when you're using generics of generic types in your code. The reason this is a problems is that for example Collection<Integer> is NOT a subtype of Collection<Number>.

Bounded wildcards should never be a return type. This forces clients to deal with wildcards explicitly. Only library designers should use wildcards.
Sometimes you actually need to do it, but it's very unlikely.

Generics and arrays don't mix very well, mostly always use generics if you can.
Some people say avoid arrays altogether, but there are cases where arrays are both prettier and faster.

Finally, the presentation ended with a few various recommendations.

Use the @Override annotation. This avoids common problems when you think you're overriding something, but really isn't, for example equals or hashCode.

Final should be used everywhere, except where there really is a reason to not do that. This minimizes mutability and is clearly thread-safe, which means you have one less thing to worry about. The only problem is readObject and clone, so take care with these.

You can use a HashMap makes a fine sparse array, with generics and autoboxing.

The Serialization Proxy pattern is really neat.
Since serialization depends on implementation details you should take care with serialization.
The pattern solves these problem by having you create a new class representing the logical state of your object, and you just use writeReplace and readResolve to use this proxy to serialize your object in an implementation independent way.

Java Puzzlers
There were some really intriguing things showcased here, and everything was Tiger-oriented. I didn't take any notes, since I had way to much fun. But I definitely recommend everyone to have a look at the presentation slides.

Super packages
Gilad Bracha had a small session about the new super packages proposed for Dolphin. As he constantly told us, nothing of this is really ready or finished. The JCP process will hash everything out later.

There is really two processes going on for modularity. One is for super packages, and regards the language changes necessary for this functionality. The other part is a module approach for packaging and distribution. The packaging has nothing to do with the language. The packaging only concerns tools and environment, more or less.

The problem with current packages concern information hiding and encapsulation. There are really hard to do this in a good way in current Java. A few solutions have been proposed for this, that are easier than a real language change.
* Don't document unexposed API
* Using static classes to provide access control to different classes
* Make a small language change that makes packages nested
The conclusion is that these doesn't suffice. They are not good enough, and very hackish solutions.

A real solution will solve the packaging problem, provide encapsulation and also allow separate compilation. All this will use separate module files for changing the semantics of a program, but still having the default way for modularity to look like current Java, for providing backwards compatibility. This is also the reason annotations won't be used for this, since it would change runtime semantics of a program, which annotations should not do.

To my eyes, the syntax and semantics Gilad showed us reminds me very much of Common Lisp packages.

Spring WebFlow
Classical web packages use free navigation, stateless systems. This is not always perfect. Some business scenarios are better represented with a controlled flow of actions. Traditionally this hasn't been the focus of Web tools. Instead, most of the current frameworks focus on providing easy to use solutions for the base case of free simple navigation. There are a few reasons for this, but the simplest reason is that controlled flow is really hard to get right.

In my opinion, WebFlow is a perfect example on how you should not solve this problem. It has the right ideas, but doesn't go far enough.

The idea in Spring WebFlow is basically to describe states and state progressions either declaratively with XML, or programmatically in code. When you've done this, WebFlow takes care of most boring stuff, like state and back buttons. It's really about inverting control to the controller, instead of having the client provide parameters that the web server uses to find out where in the flow they are.

This approach is a really good solution to the problem, but it doesn't go far enough, if you ask me. When I see executable XML I always get scared, and this case is no exception. Spring WebFlow seems to be more or less a (very) poor mans continuation server. Since you can actually have real continuation servers in Java, using an embedded script language like JavaScript or Ruby, this approach isn't good enough for me.

Groovy is like Java with some Python, Ruby and Smalltalk. It's object oriented and completely Java compatible. It has iterators, code blocks (closures), and many, many DWIM hacks.

Since the JVM is standardized and more general than Java, it can be used to innovate at the source code level. There are many scripting languages for Java.
Scripting seems to be a good way to glue business code together, since you really don't have that much business code in reality. There also is a drive to test code
with dynamic languages. So scripting is just great glue; it works like programmer duct tape.

The reason for Groovy is to have something Java developers will instantly recognize. Complete binary compatibility with Java, and possibilities to use Java without wrappers and cumbersome API's.

Groovy is basically dynamic, but also supports static typing. There is native support for lists, maps, arrays and beans..
Regexps are also part of the language. There exists some operator overloading, but nothing really lethal. Groovy also adds lots of convenience methods to the JDK, for example lots of new String-methods.

It has BSF support.

There seemed to me to exist some really hairy magic, which means that it's very hard to know exactly what's going on under the covers. A typical example was the actionPerformed parameter to some of the swing builders, which found an ActionListener interface and found the method inside that, and implemented this interface with a closure added, via 3 or 4 levels of indirection.

In conclusion, Groovy looks good on the surface, but beneath, it feels very much like Perl (in the negative sense).

JRuby showcased many fun things, the best one was JRuby on Rails actually running. Is that cool or what? A part from that, the talk was mostly aimed at people new to Ruby and JRuby. It was interesting to see that most of the people at the session hadn't heard about either Ruby or Rails one year ago! Major impact or what?

That was my day, to now. I'm off to the Java Certified Professional party! Part two comes later. Maybe much later depending on how much free drinks there are at the party.

4 kommentarer:

Anonym sa...

Good post.
If you’re looking for quick, healthy weight loss please visit Natural Weight Loss

Anonym sa...

Great Blog.

Please visit my blog if you are looking for Weight Loss Tips and diet Information.

Anonym sa...

Enjoyed your blog. If you would like free diet tips please visit Weight Loss

Anonym sa...

Small Business Information One stop Small business Shop.