Java中的传递引用

时间:2018-07-09 15:28:28

标签: java reference dependencies classpath transitive-dependency

tldr; 是什么使得有必要在构建路径中包含传递引用?

说明

我尝试分析一些用Eclipse工作区编译的Java源代码。工作区中有许多项目。

我尝试检测项目之间未使用的引用。

我的第一种方法是遍历所有项目,并从.classpath文件中获取所有引用,然后分析同一项目中的所有.java文件。如果.java文件具有来自另一个项目的import语句,则对该另一个项目的引用是必需的。 这样,我在类路径中找到了一些没有“合理性”的引用。

但是当我删除那些引用时,构建就中断了。一个这样的情况是,如果引用的类是从第三项目中扩展一个类。该项目被暂时引用,需要在构建路径中。

我想知道其他什么类型的关系(继承除外)会导致类路径中的传递引用? 那么在每个项目的继承类都位于另一个项目中的情况下,多个继承层又如何呢?

2 个答案:

答案 0 :(得分:0)

给出

  • 具有ClassA的ProjectA,它引用了Project B中的ClassB
  • 带有ClassC的第三个ProjectC

在这种情况下,您需要从projectA引用ProjectC

  • 如果ClassB从classC继承/实现,并且ClassA从ClassB调用方法。
  • 如果ClassA调用(!)来自ClassB的方法,该方法的签名包含ClassC(参数或返回值)(对于异常也是如此!)

此外,通过查看ClassA的import语句不能找到所有ProjectA的引用。

  • 如果ClassA使用了ClassC,并且与ClassA位于同一包中,则ClassC不会在ImportA中列为导入。
  • 如果ClassA以其全名(包括包名)使用ClassC,则不会创建Import语句。

答案 1 :(得分:0)

什么使它必要?

Java编译的强制性规则使其必要。 Java需要知道代码领域中的内容,以验证是否遵循规则。域是您的类路径中的jar文件集。 如果实现接口,则实现接口的非抽象实现类或类的非抽象子级需要实现接口。覆盖注释需要得到满足。从代码角度和人员角度来看,对其他方法的引用都必须可见。如果某个方法使用其他类或接口中的方法,则调用类需要知道该方法的签名。

我将如何处理?

我将使用“分类器”来指代类和接口。 您要从一组已知的经过验证的分类器和已知的未经验证的分类器开始。
从已知的未经验证的分类器开始,是目标项目中的所有分类器,而已知的验证分类器为空。

浏览每个未通过验证的分类器,找出所有未知的已使用分类器,并将其添加到未通过验证的分类器集中。

验证当前未验证的分类器在类路径上。如果找不到错误。

将已处理的分类器从未验证的类别移动到已验证的类别。

重复此过程,直到所有分类器均得到验证。

使用的分类器包括字段类型,方法返回类型,方法参数类型,参数中的变量类型,扩展类,已实现的接口,注释以及在某些情况下的Javadoc引用。根据您的项目规则,仅靠进口可能会错过一些事情。一个接口可能在同一包中,但来自不同的项目。

为什么反射和Spring配置需要超出范围?

此类操作使用基于文本的切换来完成代码。 Reflection可以使用字符串“ Package.classname”创建一个类,而无需将其标识为“已用类”。这些概念将需要超出纯源代码分析或字节码分析范围的额外处理。

如果您想更深入地学习,那么Java虚拟机规范可以使您对类文件需要运行的内容有更深入的了解。特别是Java 10规范中的“ 4.类文件格式”和“ 5.加载,链接和初始化”。 https://docs.oracle.com/javase/specs/