public
フィールドを使用しない
public
クラスの内部動作をラップする必要がある場合は、フィールドを使用しないでください。java.io.BufferedReader
例を見てみましょう。次のフィールドがあります。
private boolean skipLF = false; // If the next character is a line feed, skip it
skipLF
すべての読み取りメソッドで読み書きされます。別のスレッドで実行されている外部クラスskipLF
が、読み取りの途中での状態を故意に変更した場合はどうなりますか?BufferedReader
間違いなく問題が発生します。
public
フィールドを使用してください
このPoint
クラスを例にとります:
class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
}
これにより、2点間の距離の計算が非常に面倒になります。
Point a = new Point(5.0, 4.0);
Point b = new Point(4.0, 9.0);
double distance = Math.sqrt(Math.pow(b.getX() - a.getX(), 2) + Math.pow(b.getY() - a.getY(), 2));
クラスには、プレーンなゲッターとセッター以外の動作はありません。クラスは単なるデータ構造を表す場合、パブリックフィールドを使用することが許容されない、と持っていない、と決して行動(薄いゲッターとセッターがされていますない、ここでの行動と考えられます)。これは、このように書くほうがよいでしょう。
class Point {
public double x;
public double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
}
Point a = new Point(5.0, 4.0);
Point b = new Point(4.0, 9.0);
double distance = Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));
掃除!
ただし、覚えておいてください。クラスに動作がないことだけでなく、将来的に動作する理由もないはずです。
(これがまさにこの回答の説明です。「Javaプログラミング言語のコード規約:10.プログラミングの実践」を引用するには:
適切なパブリックインスタンス変数の1つの例は、クラスが基本的にデータ構造であり、動作がない場合です。つまり、struct
クラスの代わりにを使用した場合(Javaがサポートされている場合struct
)、クラスのインスタンス変数をパブリックにすることが適切です。
したがって、公式のドキュメントもこの慣行を受け入れます。
また、上記のPoint
クラスのメンバーが不変であることを確信している場合は、final
キーワードを追加してそれを強制できます。
public final double x;
public final double y;