3

考虑以下代码:

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.
    }
}

这段代码编译得很好;但如果你指的CalendarDemoinside,你指的是Demo.Calendar,不是java.util.Calendar

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

import java.util.Calendar;  // error: Calendar is already defined in this compilation unit

class Calendar {}

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

4

2 回答 2

3

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

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

Ideone demo

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

不过,我不会真正将其描述为“实际”用途——这只是在每种情况下使用哪个令人困惑,绝对值得避免。不过,我仍然对这个案例的存在感兴趣。


我想还有一个类似的案例:

import java.util.Calendar;

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

class Demo2 {
  class Calendar {}

  static void useNested() { ... }
}

(这些类在同一个编译单元中)。基本上和上面的想法一样。

于 2017-04-06T14:51:52.030 回答
0

我想,如果你导入一个类,它在该编译单元的全局空间中是可见的。但是,如果您将编译单元或顶级类命名为与导入相同,那么您基本上将它与导入冲突,因此 JVM 知道哪个是哪个是模棱两可的。并且由于它编译一个类,它会给出一个导入错误。

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

希望这可以帮助。

于 2017-04-06T15:16:01.263 回答