36

在线的:

private boolean someFlag;

我收到以下 PMD 警告:

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

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

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


编辑:我的课程绝对不是 bean,也不是可序列化的......

4

5 回答 5

9

我假设您的类是根据定义实现的 bean Serializable。瞬态变量将从序列化过程中排除。如果您对 bean 进行序列化然后反序列化,则该值实际上将具有默认值。

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

于 2009-02-26T10:09:08.250 回答
8

现在我懂了。

添加此定义后:

private boolean someFlag;

...很清楚这里会发生什么:

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

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

PMD 它期望有一个isSomeFlag/getSomeFlagandsetSomeFlag方法可以用来访问它的值,而不是直接访问它。

Found non-transient, non-static member. Please mark as transient **or provide accessors**.
于 2009-02-26T22:27:21.140 回答
6

查看这里发生的规则

BeanMembersShouldSerialize

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

于 2009-02-26T09:59:07.663 回答
2

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

静态成员的问题是,一次只有一个在内存中。所以它并不完全清楚反序列化时应该发生什么。应该保留旧值吗?还是缓存版本覆盖旧版本?

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

于 2009-02-26T09:58:34.857 回答
0

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

  1. 为成员添加 getter 和 setter 方法。
  2. 使用构造函数添加 final 以设置成员的值。
于 2021-03-04T17:24:51.147 回答