When you start digging into the rules for Java imports and the Java namespace (the names available to a piece of code, with or without package prefixes), things begin to get a little hairy. For example, it is illegal to have two type names that are identical within the same package. By extension, you can't import two types into your code with the same name.
On the other hand, this is precisely the sort of thing you want when dealing with methodsit's called overloading. So you may have three, four, or more methods of the same name, all taking different parameters, and javac will happily compile your code. So here's the short versiontypes must be named uniquely, methods need not be. And if you think overloading was cool in previous versions of Java, wait until you see the implications for Tiger!
Suppose you import the sort( ) method from the java.util.Arrays class:
import static java.util.Arrays.sort;
There are 18 different versions of this method, and you get all of them via overloading. However, let's also assume that you also need the Collections.sort( ) methods as well (there are two versions of that one). Since this method takes different sets of arguments than any of the 18 versions you've already imported into your namespace, just add another import statement:
import static java.util.Arrays.sort; import static java.util.Collections.sort;
Just like that, you're all set, and you get even more overloading. Now the compiler will actually decide, based on your arguments, which method, and even which class, to use to process your method call. Pretty cool!
NOTE
As cool as this is, it really increases the work that someone on the debugging or testing team has to do to figure out what's going on in your code.
...naming conflicts? As already stated, you'll get a compiler error if you import two types with the same name into your program. So the following lines would be illegal in a source listing:
import java.util.Arrays; import com.oreilly.tiger.ch08.Arrays;
You'd get the following error:
[javac] src\ch08\SortImporter.java:4: java.util.Arrays is already defined in a single-type import [javac] import com.oreilly.tiger.ch08.Arrays; [javac] ^
When it comes to naming conflicts among imported static methods, though, things are a little more obscure. I've created a simple class, shown in Example 8-3, that defines a method of sort( ) with the exact same arguments as one of the sort( ) methods in java.util.Arrays.
package com.oreilly.tiger.ch08; public class Arrays { public static void sort(float[] a) { // Do nothing // This is just used to illustrate some naming conflicts } }
Now, add you can create a naming conflict with the following lines in another class:
import static java.util.Arrays.sort; import static java.util.Collections.sort; import static com.oreilly.tiger.ch08.Arrays.sort;
In theory, there is only a potential conflict herebut both java.util. Arrays and the new Arrays class define a method with the same name (sort), that takes an identical argument set (float[]). However, the compiler will not choke on thisin fact, it doesn't even provide you a warning! As best I can tell, you're being given the benefit of the doubt as a programmer (never a good thing!). However, if you try and use the method that's a problem, things go wrong, as shown in the following code:
public static void main(String[] args) { float[] f = new float[] {5, 4, 6, 3, 2, 1}; sort(f); }
This will cause a compiler error:
[javac] src\ch08\SortImporter.java:16: reference to sort is ambiguous, both method sort(float[]) in com.oreilly.tiger.ch08.Arrays and method sort(float[]) in java.util.Arrays match [javac] sort(f); [javac] ^
So namespaces are a little tricky, and you'd do well to be careful when importing static members of the same name from multiple classes.