merlin2011
merlin2011

Reputation: 75575

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?

Upvotes: 7

Views: 6410

Answers (4)

Rogue
Rogue

Reputation: 11483

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

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

Additionally, 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.

Upvotes: 5

Thilina Koggalage
Thilina Koggalage

Reputation: 1084

This happens when your java class name and importing library name is same. In your case Scanner is refer to the class name not for the library. Changing the class name to something else will be the simplest way to solve the error.

Upvotes: 0

tenorsax
tenorsax

Reputation: 21223

This collision of a single-type-import declaration with a top-level type declaration is described at JSL §7.5.1. Single-Type-Import Declarations:

If a single-type-import declaration imports a type whose simple name is n, and the compilation unit also declares a top level type (§7.6) whose simple name is n, a compile-time error occurs.

An example cited from §7.5.1

import java.util.Vector;
class Vector { Object[] vec; }

causes a compile-time error because of the duplicate declaration of Vector.

Upvotes: 0

Aditya Peshave
Aditya Peshave

Reputation: 667

Why import java.util.* doesn't give error??

It will not throw error because there is no confusion about the class "java.util.Scanner" and your class Scanner.

When you use import as java.util.Scanner, it conflicts with your class name with the Scanner in the util.

And that is the reason for error.

Upvotes: 2

Related Questions