Books & Tools Techniques

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

Jude

Jude is my Java documentation browser. It combines Sun's definitive javadocs with the easy-to-use format of Java in a Nutshell, and tops it off with easy keyboard-based navigation and full-text searching.

Jude is available for free evaluation.

See the user's guide for more info

Java in a Nutshell

The 5th edition is now out, with complete coverage of Java 5.0!

It includes a fast-paced tutorial on the language, and a compact quick-reference for the core Java API.

Java Examples in a Nutshell

The 3rd edition, updated for Java 1.4

This edition has all-new coverage of the NIO and JavaSound APIs, completely rewritten Servlets and XML chapters, and coverage of new Java 1.4 features (assertions, logging, preferences, SSL, etc.) added througout. A great book for those who like to learn by example. 193 working examples: 21,900 lines of carefully commented code to learn from.

Java 1.5 Tiger: A Developer's Notebook

Amazon incorrectly credits me as the main author on this book. I'm actually the second author: really more of a consultant. This is a good book about all the language changes in the latest version of Java.

Effective Java

I didn't write this excellent book, but I wish I had.

Author Josh Bloch is probably best known for the collections classes in the java.util package. His experience and wisdom are apparent in this book. I learned from it and recommend it highly.

February 27, 2004

Static Import Surprises

There are some import static nuances that didn't come through in the Java 1.5 public review draft spec; I didn't understand them until I started writing actual code. First, remember that methods can be overloaded (and fields and member types can have the same name as a method) so import static can import more than one static member. It imports a name into the namespace, not any particular member. For example, this line imports the name sort:

import static java.util.Arrays.sort;

java.util.Arrays defines 19 different sort methods. The compiler performs method overload resolution with the imported name sort() just as well as it would for the qualified name Arrays.sort()

That isn't all that surprising, once you think about it. Now look at these lines of code. Illegal right?

import static java.util.Arrays.sort;
import static java.util.Collections.sort;

Actually, these lines are not illegal. The static sort() methods of these two utility classes have distinct signatures, and so these two import declarations do not introduce any namespace collisions, even though it looks like they do!

Another thing I found surprising is that you can import a static member, and then define a class that has a static member of the same name shadowing the imported member. For toplevel types, this must obviously be illegal, but it is okay for static member imports. Consider this code:

// Make "out" refer to System.out
import static java.lang.System.out;  

public class StandardOut {
    // Now we shadow the imported name
    static java.io.PrintStream out = System.err;  
    public static void main(String[] args) {
	// This line writes to System.err
	out.println("Hello, World");
    }
}

This isn't meant as criticism of static import; just an exploration of it. Static import is one of the more controversial new features of Java 1.5, but I think that overall, it is a good thing. The confusing thing about the code above is not the static import. It is the misleading line that assigns System.err to a field named "out"

February 17, 2004

Generics Glossary

Inspired by Gilad Bracha's generics tutorial, I put together a glossary for commonly used generics terminology that you might find helpful in conjunction with the tutorial or with your own investigations of generics.

The glossary is below. Comments and corrections are particularly welcome. This material will probably make its way into a book, so I have to tell you that it is Copyright © 2004 by David Flanagan, and that all rights are reserved.

generic type, generic class, generic interface

A class or interface that declares one or more type variables or formal type parameters and can be parameterized. List<E> is a generic type.

parameterized type

A generic type, with actual type arguments specified for each of its type variables. A parameterized type is sometimes referred to as an invocation of a generic type. List<Integer> is a parameterized type, for example, corresponding to the generic type List<E>.

raw type

A generic type used without actual type arguments. List is the raw type of List<E>, for example. See also erasure. When a raw type is used, the compiler substitutes the upper bound of each type variable (often this is java.lang.Object) as the actual type argument for that variable.

generic method

A method that declares a type variable or uses a wildcard in its signature.

type variable

An identifier that appears in the declaration of a generic type or generic method and represents an actual type argument of a parameterized type. Also known as a formal type parameter. For example, E is the type variable for the generic type List<E>.

formal type parameter

Another name for a type variable.

actual type argument

The type that appears in a parameterized type, or in the invocation of a generic type. For example Integer is the actual type argument of the parameterized type List<Integer>. The term type parameter is sometimes used as a synonym.

invocation

By analogy to method declarations and method invocations, the term invocation is sometimes used to refer to the parameterized type created by supplying actual type arguments for each of the type variables of a generic type. This is a synonym for parameterized type. List<String> is an invocation, of List<E>, for example.

erasure

The process of erasing the generic type information from a signature. The erasure of a generic type is its raw type.

compile-time type

A type known to the Java compiler. Generic types are compile-time types. Contrast with runtime type.

runtime type

The type of an object, as known to the Java VM at runtime, as opposed to the compile-time type known to the Java compiler. Runtime types are always raw types.

wildcard

The character ? used as an actual type argument or in the declaration of a generic method to represent an unknown type.

bounded wildcard

A wildcard with an upper or lower bound specified. For example, ? extends E is a bounded wildcard that specifies an upper bound.

bound

A constraint on a type variable or wildcard that restricts the actual type argument. An upper bound specifies a class and/or interfaces that the argument must be or extend and implement. A lower bound specifies that the actual ancestor must be a type X, or an ancestor of X. A wildcard may have an upper bound or a lower bound of a single type. A type variable can only have an upper bound, but that bound may include one or more interfaces in addition to an optional class.

Generics Tutorial, as promised

The generics tutorial I mentioned earlier, has now been released on the web (in pdf format).

It was written by Gilad Bracha, the spec lead for JSR -14 which created generics. If you want to understand generics, this is a great place to start.

February 16, 2004

Foreach

I received 14 comments on my post about the appropriate name for the "enhanced for loop". I still like my own suggestion of "auto-iterator loop", but apparently no one else did.

There doesn't seem to be a consensus, but "foreach" or variations like "for each" and "for-each" (the space or hypen help to indicate that this is not a keyword) are by far the most popular.

jez gets the award for funniest suggestion. He wants to call it the "five" loop.

February 14, 2004

Generics Tutorial Coming Soon

I just had the pleasure of reading a draft tutorial about how to actually use generics. Its written by Gilad Bracha, the spec lead for JSR 14 which defined generics. It is authoritative, but is much easier to read than the public review draft of the generics spec.

Look for this on Sun's web site next week. I found it very helpful.

February 10, 2004

What shall we call the new for loop?

Java 1.5 introduces a new looping construct that the public review draft calls the "enhanced for loop". That name is fine for the JSR process, but I don't think it will catch on for colloquial use, and I don't think it is suitable for those of us who have to write books about the new features of the language. The problems with "enhanced for" as I see them are:

  • It inaccurately implies that this new for loop is somehow an enhancement of the original one. But it is not. It is often useful in place of the original for loop, but it is a completely different construct. It would be more accurate to call it the "new for" instead of "enhanced for". But this brings us to the second problem:
  • Both "enhanced for loop" and "new for loop" are vague names that are not descriptive. They beg the questions "enhanced how?" and "what's new?"

So, I think we need a different name. All the other statements are named after their keywords. But this one shares a keyword with the original for loop, and we can't call them both "for".

There would be no problem, of course, if the new loop had its own keyword. Then it could be a "foreach" loop or a "for/in" loop. I'm on the expert group for JSR 201, however, and despite my intense lobbying, the group consensus was strongly against introducing a new keyword (other than "enum") to the language.

We're stuck with the syntax we have:

for(Type Identifier : Expression)

This syntax has lead me to consider calling this new statement the for(:) loop to distinguish it from the for(;) loop. Get it? The loop names are distinguished by the punctuation characters they use. I threatened to use these names in Java in a Nutshell when I was trying to convince the expert group to use use a different keyword. But those names are ugly and really hard to type, and I can't go through with it.

Despite the lack of a foreach keyword, I've started to see people (myself included) use the name "foreach". This new loop is a lot like the foreach loops of other languages, and it is a nice, easy and descriptive name for the statement. The problem though, is that it makes people think that there is a foreach keyword! I think we can do better, and that we should stop calling it foreach before it is too late.

The only names I can suggest are related to the fact that this loop uses (except in the case of arrays) the java.lang.Iterable and java.util.Iterator interfaces. I think we should call it the "iterator loop", "iteration statement" or "iterative for". I favor "iterator loop", although all three of these options could be used more-or-less as synonyms.

Your suggestions, comments, and votes are welcome. I've turned on anonymous comments to make it easy to get community input on this. But that will only last for a few days and then you'll have to give your e-mail address again. (Update: anonymous comments are no longer allowed)

Here are the possible names I've mentioned, for easy reference:

  • enhanced for
  • for(:)
  • foreach
  • iterator loop
  • iteration statement
  • iterative for

Update: Thanks to those who have commented and pointed out that "iterator loop" isn't descriptive enough: all loops do iterations. And many loops use iterators explicitly. It would seem that those would be "iterator loops" too. So how about auto-iterator loop. It gets a little wordy and awkward, but it is the most descriptive and specific name so far proposed. Plus, it goes with the other automatic new features of Java 1.5: auto boxing and auto-unboxing

February 09, 2004

Equality and Autoboxing

In Java 1.4 and before, the equality operators == and != allow you to compare two booleans, two numbers, or two references. Any other combination of operands was a compilation error.

In Java 1.5 auto-unboxing enters the picture. It is now possible to compare a boolean with a Boolean, and a number of primitive type with a number expressed as a reference type. That is, it is no longer a compilation error to use the equality operators with a primitive on one side and a reference type on the other. (The public review draft for autoboxing doesn't get this right. I have reported the bug, and the beta-release implementation appears to be correct.)

Now where it really starts to get interesting is when you think about primitive wrapper objects on both sides of the operator. The equality operators already have a meaning when there are two operands of reference type, so we can't unbox both sides of the operator and compare their contents: we have to compare the object references. This produces some surprising results:

public class Equality {
    public static void main(String[] args) {
        Integer i = new Integer(0), j = new Integer(0);
        // The two objects are both equal to 0
        System.out.println(i == 0 && j == 0); 
        // But they are not equal to each other
        System.out.println(i == j);
        // true: relational ops unbox both sides
        System.out.println(i <= j && i >= j);
} 

Another wrinkle is that we'd get different results if we'd used autoboxing to create the two wrapper objects we wanted to compare. Unlike the code above, this code prints true:

Integer i = 0, j = 0;
System.out.println(i == j);

The reason is that the autoboxing spec requires that small integers (-128 to 127) always box to the same wrapper object. Implementations are encouraged, but not requied, to do the same for larger values as well. So if we used 1023 instead of 0 in the code above it might print "true" or it might print "false".

None of this is intended as a criticism of autoboxing, by the way. Just an exploration of an interesting (and necessary) limitation.

February 06, 2004

Pop Quiz: Java Shift Operators

I've been brushing up on some of the more obscure corners of Java. Here's a pop quiz:

1 << 32 evaluates to:

  1. 0x100000000
  2. 0
  3. 1

Answers below...

A. 0x100000000

This value expressed in binary is 1 followed by 32 zeros. But this is the wrong answer. If you shift a byte, short, char, or int the result value is an int, and this value requires 33 bits, so it is a long. If the expression in question had been 1L << 32 this answer would be correct.

B. 0

Zero is what we get if we take the long value above and truncate it to fit in an int. Seems logical: the expression should shift 32 zero bits into the result, producing an int of all zeros. But this is wrong, too.

C. 1

This is the right answer.

The Java Language Specification specifies that the right-hand operand of the shift operators is masked so that its value is restricted to the range of meaningful values. If the left operand is a byte, short, char, then it is first promoted to an int. If the promoted left operand is an int, then all but the low 5 bits of the right operand are discarded. If the left operand is a long, then all but the low 6 bits of the right operand are discarded.

Our right operand was 32, or 00100000. When we discard all but the low 5 bits we're left with zero. So 1 << 32 is the same as 1 << 0.

I think I knew this at one time, but I would have chosen answer B.

Update

In response to a comment about Java violating the principle of least astonishment, I realized that I didn't know what the answer to this quiz was for C. I assume that Java inherits the behavior from C. I haven't written C in years, but I managed to crank out this program

int main(char **args, int argc) {
  int bits = 32;
  printf("%d\n", 1 << 32);
  printf("%d\n", 1 << bits);
}

The compiler (gcc) issues a warning on the line containing 1 << 32.

When I run it, it prints:

0
1

So, when the compiler can tell that the shift amount is too big, it gives a warning and the expression evaluates to zero. But when the compiler can't tell, it generates code that has the same behavior as C. I think Java ought to issue the warning, but having different behavior in the two cases seems like a bad thing!

February 05, 2004

Longest .NET Type Name

Inspired indirectly by my post about the longest class name in J2SE, Rob Chartier looked for the longest and shortest type names in .NET

Looks like he includes the .NET equivalents of package names and nested class names, and also considers non-public types, so his results for .NET can't be directly compared to my results for Java.

In any case, this is not a healthy arena for competition between Java and .NET!

February 04, 2004

Java 1.5 Beta 1 is out!

The Beta1 release of Java 1.5 is now available.

Sun has also published an article documenting the important new features of this release. (Hey, they stole the article title from my book) I haven't read the article carefully yet, but it looks like an informative overview.

As I noted earlier, there is still time to try out the new language features and comment on them in the JSR 201 public review.

February 03, 2004

Static Fields Through null Variables

This surpised me. The following program does not throw a NullPointerException

public class StaticFieldThroughNull {
    public static void main(String[] args) {
	Double d = null;
	System.out.println(d.MAX_VALUE);
    }
}

This really is supposed to work this way. See the JLS.

Check out the example at the end of the section of the spec linked above. Its even more surprising than mine, because it uses a method that returns null rather than a null variable.

Longest Java Class Name

Back in 1996 when I was writing the first edition of Java in a Nutshell, the book designers on the production team at O'Reilly need to know the longest class name so they could make sure it would fit in the title of reference entries. At the time it was StringIndexOutOfBoundsException at 31 characters. Tonight, I wondered if that record still stood...

So I used find, echo wc, grep, sed, and sort (isn't Unix great?) to process the filenames in the javadoc directory of J2SE 1.4.2 and find out what the longest class name is. I did not count the length of the package name, nor did I include inner classes in my count research. StringIndexOutOfBoundsException is still the longest class in java.lang, but it is matched in length by java.util.ConcurrentModificationException, and exceeded by 16 classes in less commonly used packages.

The longest of all, standing alone at 36 finger-fatiguing characters is javax.xml.transform.TransformerFactoryConfigurationError. The complete list of class names >= 30 characters is at the end of this post.

And what about short class names?

The shortest classnames have three characters and are mostly acronyms, such as the familiar java.net.URL. Two that are not acronyms are the simple and elegant Set and Map classes of java.util.

The longest class names are:

36 javax.xml.transform.TransformerFactoryConfigurationError     
35 javax.naming.AuthenticationNotSupportedException     
35 javax.naming.directory.InvalidAttributeIdentifierException     
34 java.awt.ContainerOrderFocusTraversalPolicy     
34 java.beans.beancontext.BeanContextServiceProviderBeanInfo     
34 java.security.InvalidAlgorithmParameterException     
34 org.omg.PortableInterceptor.ClientRequestInterceptorOperations     
34 org.omg.PortableInterceptor.ServerRequestInterceptorOperations     
34 org.omg.PortableServer.ImplicitActivationPolicyOperations     
33 java.beans.beancontext.BeanContextServiceRevokedListener     
33 java.util.prefs.InvalidPreferencesFormatException     
33 javax.swing.InternalFrameFocusTraversalPolicy     
33 javax.xml.transform.TransformerConfigurationException     
33 org.omg.PortableServer.RequestProcessingPolicyOperations     
32 java.beans.beancontext.BeanContextServiceAvailableEvent     
32 org.omg.PortableServer.ServantRetentionPolicyOperations     
31 java.awt.geom.NoninvertibleTransformException     
31 java.lang.StringIndexOutOfBoundsException     
31 java.nio.channels.UnsupportedAddressTypeException     
31 java.security.cert.CertificateNotYetValidException     
31 java.util.ConcurrentModificationException     
31 javax.naming.ldap.UnsolicitedNotificationListener     
31 javax.security.cert.CertificateNotYetValidException     
31 javax.swing.UnsupportedLookAndFeelException     
30 java.awt.IllegalComponentStateException     
30 java.awt.image.renderable.ContextualRenderedImageFactory     
30 java.beans.beancontext.BeanContextChildComponentProxy     
30 java.beans.beancontext.BeanContextServiceRevokedEvent     
30 java.lang.ArrayIndexOutOfBoundsException     
30 java.security.AlgorithmParameterGeneratorSpi     
30 java.security.spec.RSAMultiPrimePrivateCrtKeySpec     
30 javax.naming.InsufficientResourcesException     
30 javax.naming.OperationNotSupportedException     
30 javax.naming.directory.AttributeModificationException     
30 javax.naming.directory.InvalidAttributeValueException     
30 javax.naming.directory.InvalidSearchControlsException     
30 javax.transaction.TransactionRolledbackException     
30 org.omg.IOP.MultipleComponentProfileHelper     
30 org.omg.IOP.MultipleComponentProfileHolder     

And the shortest names are

3 java.net.URI      
3 java.net.URL      
3 java.rmi.dgc.DGC      
3 java.rmi.server.UID      
3 java.security.Key      
3 java.security.acl.Acl      
3 java.security.cert.CRL      
3 java.sql.Ref      
3 java.util.Map      
3 java.util.Set      
3 javax.crypto.Mac      
3 javax.print.Doc      
3 javax.rmi.CORBA.Tie      
3 javax.swing.Box      
3 javax.swing.text.html.CSS      
3 javax.swing.text.html.parser.DTD      
3 javax.transaction.xa.Xid      
3 org.ietf.jgss.Oid      
3 org.omg.CORBA.Any      
3 org.omg.CORBA.ORB      
3 org.omg.CORBA_2_3.ORB      
3 org.omg.IOP.IOR      
3 org.omg.PortableServer.POA      

Advertising
About
Store
Search
Google
Web this site
Archives
Syndicate

Powered by
Movable Type