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