Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

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?

like image 258
merlin2011 Avatar asked Mar 27 '14 04:03

merlin2011


People also ask

Why is it better to avoid * in import statements in Java?

Wildcard imports tell java compiler to search for class names in the given package. Hence, using wild card imports, the compile-time performance may lower a bit.

Why we do not import Java Lang package?

lang package anytime during running a program? No, java. lang package is a default package in Java therefore, there is no need to import it explicitly. i.e. without importing you can access the classes of this package.

Is import Java util * A package?

The import java. util. *; statement can be used to load the contents of the Util package in a Java program. It consists of components such as data structures, exceptions, enumerations, utility classes, etc.

What happens when we import a package in Java?

In Java, import is simply used by the compiler to let you name your classes by their unqualified name, let's say String instead of java. lang. String . You don't really need to import java.


1 Answers

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.

like image 191
Rogue Avatar answered Nov 04 '22 14:11

Rogue