merlin2011 merlin2011 - 1 month ago 8
Java Question

Why does the Java compiler complain about explicit import name conflicts but not import package.*?

The following code compiles and runs correctly.

import java.util.*;
import java.io.*;



class Scanner {
public Scanner(InputStream in) {

}
}
public class Foo{
public static void main(String[] args) {
java.util.Scanner in = new java.util.Scanner(System.in);
System.out.println(in.getClass());

Scanner in2 = new Scanner(System.in);
System.out.println(in2.getClass());
}
}


However, if I change
import java.util.*;
to
import java.util.Scanner;
, I will get the following compiler error.

Foo.java:1: error: Scanner is already defined in this compilation unit


It seems that in both cases, the compiler should be able to disambiguate equally well, so why does it only complain in the second case?

Answer

This will happen because you already have a local class named Scanner. You will need to call it with it's fully qualified name:

java.util.Scanner scan = new java.util.Scanner(System.in);

Alternatively, make your Scanner a nested static class:

public class Foo {

    private static class Scanner {

        public Scanner(InputStream in) {

        }
    }

    public static void main(String[] args) {
        java.util.Scanner in = new java.util.Scanner(System.in);
        System.out.println(in.getClass());

        Scanner in2 = new Scanner(System.in);
        System.out.println(in2.getClass());
    }
}

Why this happens

An import simply tells the compiler where to look for symbols upon compile time. I don't remember the stage off the top of my head (Preprocessing/compilation), but package imports are not explicit declarations of those class members. By saying import foo.bar.*, you are saying "Look in this package directory for Symbols upon compiling", whereas import foo.bar.Scanner is saying "Point Scanner symbols to this".

In short, a specific import is apparent that you have a symbol for "Scanner", whereas a package import does not specify this specific relation to a symbol.