2014-03-27 27 views
7

以下代码编译并正确运行。为什么Java编译器会抱怨显式导入名称冲突,但不导入包。*?

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

但是,如果我改变import java.util.*;import java.util.Scanner;,我将得到下面的编译器错误。

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

看来,在这两种情况下,编译器应该能够消除歧义同样出色,所以它为什么只在第二种情况下抱怨吗?

+3

我认为你的班级名称与它有关。你是java.util.Scanner的creatng对象,不仅仅是Scanner。所以这就是为什么它的工作时,你有导入为java.util。*; –

+0

[Java错误简单程序停止编译过程的可能的重复,请帮助](http://stackoverflow.com/questions/4094484/java-errors-for-simple-program-stop-compiling-process-please-help) –

+2

@KugathasanAbimaran,你作为一个副本链接的问题有一个非常复杂的例子,我甚至不想向下滚动阅读。虽然它的某些方面可能与这个问题重叠,但我认为它不能作为重复资格。 – merlin2011

回答

5

这将发生,因为您已经有一个名为扫描仪的本地类。您将需要调用它与它的全名:

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

此外,让您的Scanner嵌套静态类:

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

为什么发生这种情况

import简单地告诉编译器在哪里在编译时查找符号。我不记得我头顶的阶段(预处理/编译),但包导入不是这些类成员的显式声明。通过说import foo.bar.*,你说“在编译时在这个包目录中查找符号”,而import foo.bar.Scanner在说“点Scanner符号”。

简而言之,特定的导入显然表明您具有“扫描仪”的符号,而包导入并未指定与符号的特定关系。

+0

OP给出的错误不会发生在该行上。 – EJP

+0

不,导入线上发生错误。在以这种形式声明非公共类时,不能进行该导入,因此您必须为它们使用完全限定名称。 – Rogue

+0

OP在询问为什么'import java.util.Scanner'在import java.util。*'不会导致编译错误。对于相同的代码。这个答案并不完全回答这个问题。 – anonymous

2

为什么输入java.util.*不给出错?

它不会抛出错误,因为对“java.util.Scanner”类和您的类Scanner没有任何混淆。

当您使用导入为java.util.Scanner时,它与util中的Scanner与您的班级名称冲突。

而这就是错误的原因。

0

一个单一型进口申报与顶级类型声明该碰撞在JSL §7.5.1. Single-Type-Import Declarations描述:

如果单一型进口报关类型,其简单名称 是n,并且编译单元还声明顶级类型(第7.6) ,其简单名称为n,则会发生编译时错误。

§7.5.1

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

举了一个例子,因为会导致载体的重复声明的编译时间错误。

0

当您的java类名和导入的库名相同时,会发生这种情况。在你的情况下,扫描仪是指的类名不是为图书馆。将类名更改为其他内容将是解决错误的最简单方法。

相关问题