2014-03-27 10 views
7

Der folgende Code wird kompiliert und ordnungsgemäß ausgeführt.Warum beschweren sich die Java-Compiler über explizite Importnamenskonflikte, aber importieren Paket nicht. *?

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()); 
    } 
} 

Wenn ich jedoch import java.util.*; zu import java.util.Scanner; ändern, werde ich den folgenden Compiler-Fehler.

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

Es scheint, dass in beiden Fällen sollte der Compiler in der Lage sein, ebenso gut Mehrdeutigkeiten, so warum es nur im zweiten Fall beschweren?

+3

Ich denke, dass Ihr Klassenname etwas damit zu tun hat. Sie erstellen das Objekt java.util.Scanner und nicht nur den Scanner. Deshalb funktioniert es, wenn Sie java.util importiert haben. –

+0

mögliches Duplikat von [Java-Fehler für den einfachen Programmstopp-Kompiliervorgang, bitte helfen] (http://stackoverflow.com/questions/4094484/java-errors-for-simple-program-stop-compiling-process-please-help) –

+2

@KugathasanAbimaran, Die Frage, die du als Duplikat verlinkt hast, hat ein extrem verschachteltes Beispiel, das ich nicht einmal zum Lesen runterscrollen wollte. Während einige Facetten davon mit dieser Frage überlappen können, glaube ich nicht, dass es sich um ein Duplikat handeln kann. – merlin2011

Antwort

5

Dies passiert, weil Sie bereits eine lokale Klasse namens Scanner haben. Sie werden es nennen müssen damit voll qualifizierten Namen ist:

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

Zusätzlich Ihre Scanner eine verschachtelte statische Klasse machen:

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()); 
    } 
} 

Warum diese

geschieht

Ein import einfach sagt dem Compiler, wo nach Symbolen zur Kompilierzeit suchen. Ich erinnere mich nicht an die Phase von oben (Vorverarbeitung/Kompilierung), aber Paketimporte sind keine expliziten Deklarationen dieser Klassenmitglieder. Mit den Worten import foo.bar.* sagen Sie "Schauen Sie in dieses Paketverzeichnis nach Symbolen beim Kompilieren", während import foo.bar.Scanner "Punkt Scanner Symbole zu diesem" sagt.

Kurz gesagt, ein bestimmter Import ist offensichtlich, dass Sie ein Symbol für "Scanner" haben, während ein Paketimport diese spezifische Beziehung zu einem Symbol nicht angibt.

+0

Der vom OP angegebene Fehler tritt in dieser Zeile nicht auf. – EJP

+0

Nein, der Fehler tritt in der Importzeile auf. Sie können diesen Import nicht ausführen, wenn Sie nicht öffentliche Klassen in diesem Formular deklarieren, daher müssen Sie einen vollständig qualifizierten Namen für sie verwenden. – Rogue

+0

Das OP fragt, warum 'import java.util.Scanner' einen Kompilierfehler verursacht, wenn 'import java.util. *' Nicht funktioniert. Für den gleichen Code. Diese Antwort beantwortet diese Frage nicht ganz. – anonymous

2

Warum importieren java.util.* gibt keinen Fehler ??

Es wird kein Fehler ausgegeben, da es keine Verwirrung über die Klasse "java.util.Scanner" und Ihre Klasse Scanner gibt.

Wenn Sie den Import als java.util.Scanner verwenden, steht er in Konflikt mit Ihrem Klassennamen mit dem Scanner in util.

Und das ist der Grund für einen Fehler.

0

Diese Kollision einer Einzeltyp-import Deklaration mit einer obersten Ebene Typdeklaration wird bei JSL §7.5.1. Single-Type-Import Declarations beschrieben:

Wenn eine Einzeltyp-Einfuhranmeldung einen Typen, deren einfachen importiert Der Name ist n, und die Kompilierungseinheit deklariert auch einen Top-Level-Typ (§7.6) , dessen einfacher Name n ist, ein Kompilierungsfehler tritt auf.

Ein Beispiel zitierte aus §7.5.1

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

verursacht einen Fehler Compile-Zeit wegen der doppelten Erklärung Vector.

0

Dies passiert, wenn Ihr Java-Klassenname und importierender Bibliotheksname gleich ist. In Ihrem Fall bezieht sich Scanner auf den Klassennamen, nicht auf die Bibliothek. Das Ändern des Klassennamens in etwas anderes ist der einfachste Weg, den Fehler zu lösen.

Verwandte Themen