为什么Java允许导入在同一文件中定义的类?

时间:2019-02-09 06:44:07

标签: java

我创建了一个名为public class MyClassSerializer extends JsonSerializer<MyClass> implements ContextualSerializer, ResolvableSerializer { private final JsonSerializer<Object> defaultSerializer; public MyClassSerializer(JsonSerializer<Object> defaultSerializer) { this.defaultSerializer = checkNotNull(defaultSerializer); } @Override public void serialize(MyClass myclass, JsonGenerator gen, SerializerProvider provider) throws IOException { if (myclass.getSomeProperty() == true) { provider.setAttribute("special", true); } defaultSerializer.serialize(myclass, gen, provider); } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (defaultSerializer instanceof ContextualSerializer) { JsonSerializer<?> contextual = ((ContextualSerializer)defaultSerializer).createContextual(prov, property); return new MyClassSerializer((JsonSerializer<Object>)contextual); } return new MyClassSerializer(defaultSerializer); } @Override public void resolve(SerializerProvider provider) throws JsonMappingException { if (defaultSerializer instanceof ResolvableSerializer) { ((ResolvableSerializer)defaultSerializer).resolve(provider); } } 的Java文件,并将其放在文件夹TestClass.java中。在编译时,导入我在同一文件中定义的同一类,没有给我任何错误。

为什么允许这样做?

>

>

testPackage

我正在使用以下设置:

;

2 个答案:

答案 0 :(得分:3)

在某些情况下,有必要import在同一文件中定义一个类。您的示例肯定不是其中之一(您的导入只是多余的,因为同一包中的类位于同一名称空间中,这大致意味着同一包中的类是隐式导入的。)

但是看看这个(假设所有代码都在同一个文件中):

package stackoverflow;

import stackoverflow.OtherClass.OtherClassInner;

public class Main {
    public static void main(String[] args) throws Exception {
        OtherClassInner inner = new OtherClassInner();
    }
}

class OtherClass {
    static class OtherClassInner {

    }
}

在这种情况下,MainOtherClassInner不在同一个命名空间中,因此它必须完全限定stackoverflow.OtherClass.OtherClassInner(或通过OtherClass.OtherClassInner将其引用为{{ 1}}和Main不需要互相导入),也不必如上面的片段所示那样将其导入。

为了清楚说明为什么需要进行导入,请考虑以下因素(在同一文件中有两个OtherClass):

OtherClassInner

答案 1 :(得分:1)

据我所知,编译器对要编译的类和所有导入的类进行了概要分析,并确保多个不同的概要分析类在给定范围内不具有相同的名称(即,不同的文件不会使用类导入不同的文件同名)。多个文件导入同一个类(或同一个文件)非常普遍,因此在这种情况下这种情况并非“不正确”。在这种情况下,编译器会简单地指出它已经读取了一个类,因此下次将其包含进来时,它会意识到它已经读取了该类并使用了现有的概要分析类。在编译器对每个类进行了概要分析(可能预先形成了类层次结构)之后,它将经历并编译其已概要分析的类。

此方法应提供与显式处理给定情况相同的结果,但是代码更简单,因此留出更少的错误空间并提高了性能,并可能处理其他“奇怪”情况,否则可能导致错误编译由于必须专门照顾他们。

许多编译器都避免了诸如瘟疫之类的情况,因为它们没有执行此概要分析步骤,因此,每次发生此类情况时,它们都会冒着导致编译器进入无限循环的风险,因为它们每次都不断重新启动编译同一文件因为他们将其视为依赖项,因此必须先进行编译,然后才能编译原始(和相同)文件。