webdevqa.jp.net

Java非一時的なクラスメンバーに対するPMD警告

オンライン:

private boolean someFlag;

次のPMD警告が表示されます。

非一時的、非静的メンバーが見つかりました。一時的なものとしてマークするか、アクセサーを提供してください。

この警告が表示される理由とその意味を誰かに説明してもらえますか? (私はそれを修正する方法を理解しています、なぜそれがそこにあるのか理解していません...)

私は他の多くのメンバー宣言でもこれを取得しています...


EDIT:私のクラスは間違いなくBeanではなく、シリアル化できません...

34
Yuval Adam

あなたのクラスは、定義上Serializableを実装するBeanだと思います。一時変数は、シリアル化プロセスから除外されます。 Beanをシリアル化してから逆シリアル化すると、値は実際にはデフォルト値になります。

PMDは、ここでシリアル化可能なBeanを処理していることを前提としています。 Beanの場合、すべてのメンバー変数に対してゲッター/セッターが必要です。これらを省略しているので、メンバー変数がBeanの一部ではないことを意味します。したがって、シリアル化する必要はありません。その場合は、シリアル化から除外する必要があります。これは、変数を「一時的」としてマークすることによって行います。

9
tcurdt

わかりました、今私はそれを取得します。定義を追加した後

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**.
7

起こっているルールを参照してください ここ

BeanMembersShouldSerialize

クラスがBeanである場合、またはBeanによって直接的または間接的に参照されている場合は、シリアル化可能である必要があります。メンバー変数は、一時的、静的としてマークするか、クラスにアクセサーメソッドを含める必要があります。変数を一時的なものとしてマークすることは、最も安全で簡単な変更です。アクセサメソッドはJava命名規則に従う必要があります。つまり、変数fooがある場合は、getFooメソッドとsetFooメソッドを指定する必要があります。

6
toolkit

トランジェントは、jvmシリアル化のヒントとして使用され、ストリーム/ディスクにクラスを書き込むときに無視する必要があります。したがって、インスタンスが回復されてメモリ内のオブジェクトになると、フィールドはnullになります。

静的メンバーの問題は、一度に1つのメンバーしかメモリに存在しないことです。したがって、逆シリアル化時に何が起こるかは完全には明確ではありません。古い値を保持する必要がありますか?または、キャッシュされたバージョンが古いバージョンを上書きしますか?

何をすべきか:Serializableクラスでは静的フィールドをまったく使用しないでください。それを別の場所に移動するか、さらに良いことに、静的メンバー/シングルトンをまったく使用しないでください。それらはグローバルな状態を導入し、多くの問題や悪いOO設計につながる可能性があります。

2