Cycle Finder 工具

用法

下面是一个简单的示例,其中包含 Foo 和 Bar 这两个类之间的循环。

cat Foo.java
package mypkg;
public class Foo {
  Bar myBar;
}

cat Bar.java
package mypkg;
public class Bar {
  Foo myFoo;
}

cycle_finder Foo.java Bar.java
acceptAST: mypkg/Bar.java
acceptAST: mypkg/Foo.java

***** Found reference cycle *****
Bar -> (field myFoo with type Foo)
Foo -> (field myBar with type Bar)
----- Full Types -----
Lmypkg/Bar;
Lmypkg/Foo;

1 CYCLES FOUND.

在输出中,您首先会看到要解析的每个 Java 文件的 acceptAST。这只是提供参考信息的日志记录。

对于每个周期,将输出两个列表。第一个列表包含该周期的说明。参考图中的每条线列出了一条边。边缘说明会显示出发地类型,后跟有关出发地类型如何指代目标类型的说明。

第二个列表(位于 Full Types 下)显示周期中每种类型的唯一类型键。这非常有用,因为它提供了每种类型的完整软件包。

排除列表

部分已检测到的循环不需要任何纠正措施。这可能是因为该循环包含不需要取消分配的长期存在的对象。或者,该工具可能会根据特定字段的类型检测理论循环,在这种情况下,可以证明涉及的对象绝不会形成循环。对于这些情况,我们可以使用禁止列表文件来不报告这些循环。

该工具接受使用 --suppress-list 选项来禁止显示列表文件。排除列表文件是包含一行条目的纯文本文件。禁止名单条目可以采用以下示例中所示的 4 种形式之一。建议在添加禁止名单条目时尽可能具体,以避免抑制合法循环。使用“#”可以添加注释字符。

# Specifies that "fieldA" in ClassA will not refer to any object that is a subtype of ClassB.
FIELD my.pkg.ClassA.fieldA my.pkg.ClassB

# Suppresses all cycles containing "fieldA" in ClassA.
FIELD my.pkg.ClassA.fieldA

# Suppresses all cycles containing any field of ClassA.
TYPE my.pkg.ClassA

# Suppress all cycles containing the Inner's outer reference to ClassA.
OUTER my.pkg.ClassA.Inner

# Suppress all cycles containing the outer reference from an anonymous class declared in myMethod.
OUTER my.pkg.ClassA.myMethod.$

# Suppresses all cycles containing any type in package "my.pkg".
NAMESPACE my.pkg