Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么可以导入与嵌套类同名的类?_Java_Language Specifications - Fatal编程技术网

Java 为什么可以导入与嵌套类同名的类?

Java 为什么可以导入与嵌套类同名的类?,java,language-specifications,Java,Language Specifications,考虑以下代码: import java.util.Calendar; class Demo { class Calendar {} public static void main (String[] args) { // System.out.println(Calendar.DAY_OF_WEEK); // Would be an error. } } 这段代码编译得很好;但是如果您在Demo中引用Calendar,那么您指的是Demo.Calend

考虑以下代码:

import java.util.Calendar;

class Demo
{
    class Calendar {}

    public static void main (String[] args) {
      // System.out.println(Calendar.DAY_OF_WEEK);  // Would be an error.
    }
}
这段代码编译得很好;但是如果您在
Demo
中引用
Calendar
,那么您指的是
Demo.Calendar
,而不是
java.util.Calendar

进口显然是多余的;但是,考虑到不允许您导入与在同一编译单元(per)中定义的顶级类具有相同简单名称的类,允许这样做似乎很奇怪:


第一个代码示例中的这种导入不会是编译时错误,这有什么实际原因吗?

我能想到的唯一情况是,您有一个两次(或更多)嵌套的类,其名称与导入相同:

import java.util.Calendar;

class Demo {
  static class Nested {
    static class Calendar {}

    static void useNested() {
      System.out.println(Calendar.class);  // Demo.Nested.Calendar
    }
  }

  static void useImported() {
    System.out.println(Calendar.class);  // java.util.Calendar
  }

  public static void main(String[] args) {
    Nested.useNested();
    useImported();
  }
}

在这种情况下,嵌套的
日历
嵌套的
类的范围之外不会自动可见,因此导入的
日历
类在外部使用,例如在
使用导入的
方法中

我不会真的把它描述为一个“实际”的用法,尽管-它只是简单地混淆了在每个上下文中使用的是什么,并且绝对值得避免。不过,我仍然对这个案子的存在感兴趣


我想还有另一个类似的例子:

import java.util.Calendar;

class Demo {
  static void useImported() { ... }
}

class Demo2 {
  class Calendar {}

  static void useNested() { ... }
}

(这些类位于同一编译单元中)。基本上与上面的想法相同。

我想,如果导入一个类,它在编译单元的全局空间中是可见的。但是,如果将编译单元或顶级类命名为与导入相同的名称,则基本上是将其与导入相冲突,因此JVM不清楚哪个是哪个。由于它编译了一个类,它将为导入提供一个错误

另外,当它在另一个类中时,您将在那里跟踪导入。它与全局/类级变量和方法级变量相似,如果使用相同的名称定义,则隐藏它们


希望这能有所帮助。

“因此JVM会有歧义”这不是歧义,您只是不能引用导入的类,所以它被阻止了。这就像防止类似于
“instanceof Integer
”这样的事情:这对JVM来说并不含糊不清,它可能只是指示程序员错误。@AndyTurner-我解释的是假设JVM允许在同一编译单元中导入和顶级类名相同。对不起,也许我不清楚。是的,我明白这一点,我是说它不是含糊不清的:它是冗余的,就像
“instanceof Integer
是一种冗余的写入
false
的方式,因此编译器不允许它。它不是冗余的;这是无效的。话虽如此,我很确定这是合法的,因为语言规范没有禁止它。可能这是语言设计者没有考虑的情况。你误读了JLS。它并不禁止导入与顶级类相同的名称,如果“编译单元还声明了一个简单名称为
n
”的顶级[sic]类型,则它禁止导入名称。“这不是你所表现出来的情况。”勒布洛赫我不明白你所指出的区别。请您提供一个例子来说明这种区别?在您的例子中,顶级类的名称是什么?它是
日历
还是其他什么东西,比如说,
演示
?“我很惊讶规范中没有规定第一个案例将被禁止。”;这是一种心理反应。唯一的冲突是导入的简单名称与编译单元中顶级类的名称匹配。区别在于,它只在命名冲突的顶级类的定义中禁止这样做。类完全可以自由地导入与编译单元中的某个顶级类相同的名称。所以
Demo
可以导入
Calendar
很好。
import java.util.Calendar;

class Demo {
  static void useImported() { ... }
}

class Demo2 {
  class Calendar {}

  static void useNested() { ... }
}