InfoQ: Are there major changes between the previous version of 'Effective Java' and this one, or is it more of a refinement of existing ideas?

Joshua Bloch: It's a combination of additions and refinements. The second edition covers all the new language features. It has a chapter on generics, one on enums and annotations, and items on the for-each loop, autoboxing, varargs, and static import. The concurrency chapter has been thoroughly revised in light of java.util.concurrent. And all the existing items have been revised to reflect these new features, and to reflect seven more years of experience with the platform.

That said, I worked very hard not to alter the feel of the book. Hopefully it will feel like an old friend to readers of the first edition -- a little wiser and little heavier (21 items and 83 pages, to be precise), but an old friend.

InfoQ: How have the numerous new language features which have been added to Java since 2001 changed the Java development process, and what are the major differences between then and now?

Joshua Bloch: How the new features have changed the development process depends on what sort of development you do. For the most part, they've made the process more pleasant and reduced the likelihood that the resulting programs will contain bugs. Features like the for-each loop and enum types eliminate a lot of boilerplate, which helps achieve both of these ends.

Generics make your programs safer and largely eliminate the need for manual casting, but they do introduce a certain amount of complexity. Wildcard types are complicated and parameterized type declarations are wordy. The "impedance mismatch" between arrays and generics can be a pain. I do my best to teach programmers how to cope with all of this in the new generics chapter.

Annotations have significantly changed the development process if you're using a framework that makes heavy use of them. Take a look at the Guice framework to see how this can work. Guice combines annotations and generics to yield unprecedented levels of type safety when wiring and testing objects in a large application.

InfoQ: Do you see the principles in Effective Java as being applicable to other similar languages such as C#?

Joshua Bloch: Absolutely. Many C# programmers have told me that they found the first edition to be a great help. For the most part, Effective Java is a book about good programming practices. Many of these practices transcend the details of the language. Of course there are areas that are very much tied to the language. For example, Java and C# have very different takes on generics.

InfoQ: Does the expansion of the JVM to include dynamic languages such as JRuby and Jython provide better avenues for targeting the Java API than the Java language does?

Joshua Bloch: Dynamic languages are an important component of the overall Java platform ecology. I believe that these languages still constitute a small minority of JVM use, but who knows what the future may hold? I think it's great that so many languages benefit from the community's investment in the Java platform.

InfoQ: What are the core principles and key takeaway points that Effective Java aims to convey to the reader?

Joshua Bloch: Same as it ever was: Always strive to write simple, clear, and correct programs. It is penny wise and pound foolish to do otherwise. Style does matter. It pays real dividends in terms of correctness, usability, robustness, and maintainability. Also, it's way more fun to write good programs than bad ones.

InfoQ: Assuming that a third edition will eventually be written, what would you like to see change between now and then to make the process of programming effectively in Java better?

Joshua Bloch: I don't really want to see any major changes in the Java language. It's already as complex as a language should be. I could see some minor changes along the lines of improved type inference on generic constructor invocations. I might like some more substantial changes to the generic type system if they could reduce the need for unsafe casts and the like. I'd be thrilled if generics could be made to work for primitive types, but it may be a bit late for that: in the presence of this feature, autoboxing would become a wart.

InfoQ: Has the increased power of tooling and the introduction of easy code refactoring made programming effectively in Java easier or harder?

Joshua Bloch: Easier! People just love modern IDEs and all they do to accelerate the development process. Programmers do refactorings that they just wouldn't have bothered with if they had to do them manually. And static analysis, of the sort performed by FindBugs and by the code inspection facilities in modern IDEs is a real blessing. We all make mistakes, and it sure is nice to have an automated assistant looking over your shoulder.

InfoQ: Do you believe that the principles in Effective Java can be integrated into the existing tooling (e.g. Eclipse or NetBeans) in order to provide a set of best practices right in the IDE?

Joshua Bloch: Some of them can. In fact, some of the have:) The same is true for Java Puzzlers. Many puzzlers have been turned into code inspections in IDEs, and bug patterns in FindBugs. I think it's just great when these practices can be automated.

InfoQ: Do you believe that other tools and processes such as unit testing, Test-driven development or pair programming also aid in programming effectively in Java?

Joshua Bloch: Absolutely. Unit testing is key. And writing your tests first is a great thing. Pair programming works very well for some people, as do variants such as "buddy programming" (where you show your code to someone else after you've written it, and refactor as necessary together). Writing code in a vacuum is bad thing. Code reviews (which I view as another variant) are essential. I'm a huge fan of most agile practices, with one exception. I do not believe that "the code is the documentation". When you're writing reusable modules, it's absolutely critical to specify their behavior in prose. JavaDoc is great for that.

InfoQ: In conjunction with Effective Java, there are also many things that one can do to write Ineffective Java. What do you believe are the biggest mistakes one can make which lead to ineffective Java?

Joshua Bloch: I don't want to sound like a broken record, but here are two biggies:

I'm very excited about this edition, and it is great to see InfoQ offering the generics chapter so we can take a peek before the book begins to ship. I don't know if this is the version that went to press, but I think there is a small error on a code snippet. On the bottom of page 121 we find:

I am not sure I agree with your change entirely since the index of the array is never referenced in your code from within the for-each loop. However, I can see what you mean by the book version being incorrect since snapshot is not used anywhere.

You are absolutely right. What's worse, I caught this problem before the book went to print. I fixed it in the code example bundle (which will soon be posted on the book's web site). Somehow I failed to propagate the change into the book. I hope this is the only place where I did this.

I will fix the problem in the second printing and put it on the (currently nonexistent) errata page as soon as possible.