让我们在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();
}
}
可以看出,只有A
类Main
的直接导入。但是,我们正在调用从b
返回的方法A.a()
。
我的问题是,虽然我们在Main
和B
之间没有直接的导入依赖关系,但它们仍然被认为是直接依赖的吗?例如,当我分析类之间的依赖关系时?
答案 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)