| Books & Tools | Techniques | |
|
Comprehensive coverage of Ruby 1.8 and 1.9
"The New Most Important Ruby Book" JudeJude 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 NutshellThe 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 NutshellThe 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 NotebookAmazon 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 JavaI 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, 2004Static Import SurprisesThere 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, 2004Generics GlossaryInspired 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.
Generics Tutorial, as promisedThe 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, 2004ForeachI 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, 2004Generics Tutorial Coming SoonI 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, 2004What 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:
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:
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, 2004Equality and AutoboxingIn 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, 2004Pop Quiz: Java Shift OperatorsI've been brushing up on some of the more obscure corners of Java. Here's a pop quiz: 1 << 32 evaluates to:
Answers below...
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, 2004Longest .NET Type NameInspired 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, 2004Java 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, 2004Static Fields Through null VariablesThis 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 NameBack 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
Archives
April 2008
March 2008 February 2008 January 2008 November 2007 October 2007 September 2007 August 2007 July 2007 June 2007 May 2007 April 2007 March 2007 February 2007 January 2007 December 2006 November 2006 October 2006 September 2006 August 2006 July 2006 June 2006 May 2006 April 2006 March 2006 January 2006 December 2005 November 2005 October 2005 September 2005 August 2005 July 2005 June 2005 April 2005 March 2005 February 2005 December 2004 October 2004 September 2004 July 2004 June 2004 May 2004 April 2004 March 2004 February 2004 January 2004 Syndicate
|