The Artima Developer Community
Sponsored Link

Computing Thoughts
Generics: Bounds Puzzle
by Bruce Eckel
October 24, 2005
Summary
I was poking around in the Standard Java Libraries looking for examples of generic code, and came across something curious.

Advertisement

This is in the package java.lang.reflect (comments have been edited out):

public interface TypeVariable<D extends GenericDeclaration> extends Type {
    Type[] getBounds();
    D getGenericDeclaration();
    String getName();
}

Why is this curious? A generic parameter "erases to its first bound," which means that the compiler effectively replaces the parameter with its first bound. In this case, that bound is simply GenericDeclaration.

But if you look at the code, you'll see that there is no need for generics to be used here. You can just say that the return type of getGenericDeclaration() is GenericDeclaration, and skip the use of generics. So I think it should look like this, instead:

public interface TypeVariable extends Type {
    Type[] getBounds();
    GenericDeclaration getGenericDeclaration();
    String getName();
}

That's my take on it, anyway. Perhaps you can see something that I havent.


Here is the Python program I used to hunt for generic declarations. It has a serious flaw in that it will only find such declarations where a '<' and '>' appear on the same line (I know it's possible to write a regular expression that deals with all the possibilities of multiple lines and nested angle brackets, but I just wanted to do a quick scan, and regular expressions like that hurt my brain. Please feel free to suggest a correction).

The program attempts to remove any generic argument list that looks "complex enough to be justified," and just tries to find the ones that might be "too simple."

'''Searches through standard Java source code files'''
# Uses Python 2.4
import os, re

src = r"C:\ProgTools\Java\src" # Your Java source directory
output = file("GenericArgumentLists.txt", 'w')

# Limit: only matches when they're all on one line:
genericArglist = re.compile('<.*?>')

# Walk the directory tree looking for appropriate Java files
for javaFile in (os.path.join(root, name)
        for root, dirs, files in os.walk(src)
        for name in files if name.endswith(".java")):
    lines = file(javaFile).readlines()
    for index, line in enumerate(lines):
        methodArgs = genericArglist.search(line)
        if methodArgs:
            match = methodArgs.group(0)
            if match.find("?") == -1 \
            and match.find("extends") != -1 \
            and line.find("Class<") == -1 \
            and match[1:].find("<") == -1:
                print>>output, javaFile, "(" + str(index) + "):\n\t", line.rstrip()

Talk Back!

Have an opinion? Readers have already posted 10 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Bruce Eckel adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Bruce Eckel (www.BruceEckel.com) provides development assistance in Python with user interfaces in Flex. He is the author of Thinking in Java (Prentice-Hall, 1998, 2nd Edition, 2000, 3rd Edition, 2003, 4th Edition, 2005), the Hands-On Java Seminar CD ROM (available on the Web site), Thinking in C++ (PH 1995; 2nd edition 2000, Volume 2 with Chuck Allison, 2003), C++ Inside & Out (Osborne/McGraw-Hill 1993), among others. He's given hundreds of presentations throughout the world, published over 150 articles in numerous magazines, was a founding member of the ANSI/ISO C++ committee and speaks regularly at conferences.

This weblog entry is Copyright © 2005 Bruce Eckel. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us