非瞬态类成员上的Java PMD警告

时间:2009-02-26 09:45:11

标签: java coding-style pmd

在线:

private boolean someFlag;

我收到以下PMD警告:

  

找到非瞬态,非静态成员。请标记为瞬态或提供访问者。

有人可以解释为什么会出现此警告及其含义? (我明白如何解决它,我不明白为什么它在那里......)

我在许多其他成员声明中也得到了这个......


编辑:我的班级肯定不是bean,也不是可序列化的......

5 个答案:

答案 0 :(得分:7)

我假设你的类是一个定义为Serializable的bean。瞬态变量将从序列化过程中排除。如果序列化然后反序列化bean,则该值实际上将具有默认值。

PMD假设您在这里处理可序列化的bean。对于bean,它应该具有所有成员变量的getter / setter。由于您省略了这些,因此您暗示您的成员变量不是bean的一部分....因此不需要序列化。如果是这种情况,您应该将其从序列化中排除。您可以将变量标记为“瞬态”。

答案 1 :(得分:7)

好的,现在我明白了。 添加定义后

private boolean someFlag;

很清楚这里发生了什么:

此错误消息确实引用了访问架构。 PMD声明bean引用的类也必须遵循bean模式。

最有可能支持属性风格的访问,如MyBean.referredClass.someFlag将被翻译为someObject.getReferredClass()。getSomeFlag()

PMD它期望有一个isSomeFlag()/ getSomeFlag()和setSomeFlag()方法,您可以通过它来访问它的值,而不是直接访问它。

Found non-transient, non-static member. Please mark as transient **or provide accessors**.

答案 2 :(得分:6)

查看正在发生的规则here

  

BeanMembersShouldSerialize

     

如果一个类是一个bean,或者是一个bean直接或间接引用它,那么它需要是可序列化的。成员变量需要在类中标记为transient,static或者具有访问器方法。将变量标记为瞬态是最安全和最简单的修改。访问器方法应遵循Java命名约定,即如果您有变量foo,则应提供getFoo和setFoo方法。

答案 3 :(得分:2)

transient用作jvm序列化的提示,它应该在流/磁盘中写入类时忽略它。因此,如果您的实例已恢复并成为内存中的对象,则该字段将为null。

静态成员的问题是,一次只有一个在内存中。因此,不完全清楚反序列化应该发生什么。是否应保留旧价值?或缓存版本覆盖旧版本?

你应该做什么:根本不要在Serializable类中使用静态字段。把它移到其他地方,或者更好的是,根本不要使用静态成员/单身人士。他们引入了一个可能导致许多问题和糟糕OO设计的全球状态。

答案 4 :(得分:0)

您可以通过两种方式解决此问题:

  1. 为成员添加 getter 和 setter 方法。
  2. 使用构造函数添加 final 以设置成员的值。