没有显式导入的类之间的依赖关系

时间:2018-05-14 08:44:32

标签: java import dependencies

让我们在Java中考虑这个简单的类层次结构:

A类:

package a;

import b.B;

public class A {
    public B a() {
        return new B();
    }
}

B级:

package b;

public class B {
    public void b() {
        System.out.println("B!");
    }
}

班级主要:

import a.A;

public class Main {
    public static void main(String[] args) {
        A a = new A();
        a.a().b();
    }
}

可以看出,只有AMain的直接导入。但是,我们正在调用从b返回的方法A.a()。 我的问题是,虽然我们在MainB之间没有直接的导入依赖关系,但它们仍然被认为是直接依赖的吗?例如,当我分析类之间的依赖关系时?

2 个答案:

答案 0 :(得分:5)

是的,这是一种直接依赖。您不必向编译器声明它,因为它可以查看返回B的方法签名并为您解析该类。

如果编译器找不到B(或者想要在其上调用的方法),则会收到有关缺少类的编译时错误。

在运行时,当您加载一个类时,它还会加载方法签名中引用的所有类(如果找不到这些类,则会失败)。

另请注意,import语句本身仅适用于编译器。它们对生成的类文件没有影响。这意味着如果您导入了10个未使用的类,那么这些类将不会成为依赖项(编译器仍然会在导入部分中抱怨它们丢失,但它们不会在运行时加载)。

答案 1 :(得分:2)

编译时,编译器会链接依赖项。

这意味着,由于使用了a.A并导入了a.A,因此.class的导入也会添加到编译(或链接,IIRC)中。

此时,如果查看生成的b.B文件,您会看到它导入// for all non-C-string cases template<typename T, std::enable_if_t<!std::is_same_v<std::decay_t<T>, const char*>>* = nullptr> A<typename std::remove_reference<T>::type> make_A(T&& a) { return A<typename std::remove_reference<T>::type>(std::forward<T>(a)); } // in case a C-string got passed A<std::string> make_A(const std::string& str) { return A<std::string>(str); } int main() { auto a = make_A("abacaba"); auto b = make_A(5); }

所以回答你的问题:在java级别,它们是间接依赖的。编译后 - 直接依赖。

(我可能错了,但这是我对它的理解。如果有人知道更好,请务必纠正我:D)