内部类可以是静态的¶
ID: java/non-static-nested-class
Kind: problem
Security severity:
Severity: recommendation
Precision: high
Tags:
- efficiency
- maintainability
Query suites:
- java-security-and-quality.qls
嵌套类允许将相关的关注点进行逻辑分组,从而提高封装性和可读性。但是,使用嵌套类时,您应该注意一个潜在的缺点。
任何非静态嵌套类都隐式地保留其“封闭实例”。这意味着
嵌套类具有一个隐式定义的字段。该字段保存对构造嵌套类的封闭类的实例的引用。
嵌套类的构造函数具有一个隐式参数。该参数用于传入封闭类的实例。然后,将对该实例的引用存储在上面提到的字段中。通常,这很有用且必要,因为非静态嵌套类实例可以访问其封闭类的实例状态。但是,如果嵌套类不需要此实例状态,则这会使嵌套类实例的大小大于必要,并且对封闭类的隐藏引用通常是造成微妙内存泄漏的原因。
建议¶
当嵌套类不需要封闭实例时,最好将嵌套类声明为 static
,以避免隐式字段。这样,嵌套类的实例将变得更小,并且对封闭类的隐藏引用将变得显式。
如果在构造嵌套类实例时需要对封闭类实例的引用(但之后不需要),则应重构嵌套类的构造函数,以便显式地为其提供对封闭实例的引用。
如果嵌套类引用封闭类实例的类型变量,请考虑通过该类型变量对嵌套类进行参数化。
参考¶
J. Bloch,Effective Java(第二版),第 22 项。Addison-Wesley,2008 年。
Java 语言规范:8.1.3. 内部类和封闭实例。
Java 教程:嵌套类。