Java OSGi类加载:为什么BND导入未直接引用的类?

Java OSGi类加载:为什么BND导入未直接引用的类?,java,osgi,classloader,bnd,Java,Osgi,Classloader,Bnd,束-A: FooA.java package com.foo.a; import com.foo.b.FooB; class FooA { FooB b = new FooB(); } B包: FooB.java: package com.foo.b; import com.foo.c.FooC; class FooB { public FooC foo() { ... } } 束-C: 简而言之,我有3个捆绑包-A,B和C 捆绑包A直接引用

束-A:

FooA.java

package com.foo.a;

import com.foo.b.FooB;

class FooA {
    FooB b = new FooB();
}
B包:

FooB.java:

package com.foo.b;

import com.foo.c.FooC;

class FooB {

    public FooC foo() {
       ...
    }
}
束-C:

简而言之,我有3个捆绑包-A,B和C

捆绑包A直接引用捆绑包B,捆绑包B引用C。 如您所见,FooA不使用FooB中返回FooC的方法,因此bundle A中不直接引用FooC

那么为什么BND将OSGi导入包包含到com.foo.c中呢?
按照我的理解,bundle A只需要bundle B就可以自行解析。另一方面,Bundle B需要C。但是如果在那里没有使用C,为什么A直接需要C呢?

我认为bnd会为您使用的类导入外部可见的所有类。当您使用类FooB时,您可能需要访问它可能需要作为参数或作为结果返回的所有类


如果要避免依赖关系,可以创建一个只显示真正需要的方法的接口。然后,您可以在bundle B中使用该接口创建一个服务,并且只能使用bundle a中的接口访问该服务。

查看FooA类的字节码。你会在里面看到FooC。使用Java反编译器工具查看使用它的原因。一些反编译器创建的代码显示的信息比原始java代码多一点。我看不出这是为什么,但这是另一个例子:

我猜您有以下功能:

public class ListProvider {

    public static ArrayList getMyList() { return null; }

}
另一个类称之为:

List myVar = ListProvider.getMyList();

您将在另一个类的字节码中看到ArrayList。原因是字节码leven上使用的函数签名也包含返回类型。

好的,我理解引入接口的想法。但我并不是在寻找解决这个问题的方法。我想做的是了解这个问题-为什么BND包含这个包?这个包裹真的需要吗?如果手动删除导入,是否会中断类加载?为什么?A不是直接使用C…这完全取决于java是需要C来实例化类A还是在您的案例中使用它。如果您删除了导入,那么看看会发生什么是很有趣的。如果它仍然有效,那么也许bnd可以改进,但通常它是相当准确的。。不过你还是应该尝试使用接口和服务。。。这是真正解耦模块的唯一方法。