この時点で、Javaのパブリックフィールドは悲劇的な歴史的な設計上の欠陥にすぎませんか?[閉まっている]


17

この時点では、オブジェクトの状態にパブリックフィールドを使用することは基本的に決してすべきではないというのは、Javaの正統性のようです。(必ずしも同意するわけではありませんが、それは私の質問とは関係ありません。)それを考えると、今日からJavaのパブリックフィールドが言語設計の誤り/欠陥であったことは明らかです。それとも、今日でも言語の有用かつ重要な部分であるという合理的な議論がありますか?

ありがとう!

更新: C#、Python、Groovyなどのよりエレガントなアプローチについて知っています。これらの例を直接探しているわけではありません。バンカーの奥深くにまだ誰かがいるのではないかと思っているだけで、公共の場がどれほど素晴らしいのか、大衆はただの羊なのかなどについてつぶやいています。

更新2:明らかに静的な最終公開フィールドは、公開定数を作成する標準的な方法です。オブジェクトの状態(不変の状態でさえ)にパブリックフィールドを使用することについてもっと言及していました。パブリックフィールドを定数ではなく、状態ではなく使用する必要があるという設計上の欠陥のように思えます。言語のルールは、ガイドラインではなく構文によって自然に実施されるべきです。


2
それらが実際に欠陥であるというあなたの根拠は何ですか?
アーロンマクアイバー

1
Javaで記号定数式を作成する別の方法はありますか?
エドワードストレンジ

@Aaron私はそれらが欠陥であると述べていませんでした、私はそれが人が公共の場を決して使うべきではないというこの時点でそれが正統であると知覚したと述べていました。その認識は間違っているかもしれませんが、実際に私が認識したものです。
アビフラックス

@Crazy Eddieその使用法を忘れてしまったので、私はフィールドのより一般的な使用法、州を考えていました。質問を編集します。
アビフラックス

回答:


14

フィールドが最終的なものであり、アプリケーションの内部でのみ使用され、他のアプリケーションのAPIで公開されていない限り、私はそれらが好きです。これにより、コードが短くなり、読みやすくなります。

パブリックフィールドを公開すると、実装も公開されるため、APIでパブリックフィールドを公開しないでください。getXXX()代わりにメソッドとして公開する場合は、APIインターフェイスを変更せずに実装を変更できます。たとえば、リモートサービスから値を変更して取得できますが、APIを使用するアプリケーションはこれを知る必要はありません。

これは、不変クラスのpublic finalフィールドの実行可能な設計です。

効果的なJavaから:

項目14:パブリッククラスでは、パブリックフィールドではなくアクセサメソッドを使用します

...クラスがパッケージプライベートであるか、またはネストされたプライベートクラスである場合、そのデータフィールドの公開に本質的に問題はありません。このアプローチでは、アクセッサメソッドアプローチよりも混乱が少なくなります。

パブリッククラスがフィールドを直接公開することは決して良い考えではありませんが、フィールドが不変であれば有害ではありません。

JavaBeansの代わりに不変のPOJOを使用すべきではない理由も参照してください


ただ疑問に思うのは、APIで公開しない理由は何ですか?
スティーブンジュリス

2
@Steven:パブリックフィールドを公開することで、実装も公開するためです。getXXX()代わりにメソッドとして公開する場合は、APIインターフェイスを変更せずに実装を変更できます。たとえば、リモートサービスから値を変更して取得できますが、APIを使用するアプリケーションはこれを知る必要はありません。
ジョナス

@Jonas:これらは一般に、そもそも定数の候補ではありません。
スティーブンジュリス

@Steven:そもそも定数についてではなく、不変クラスのpublic finalフィールドについてです。たとえば、なぜJavaBeansの代わりに不変のPOJOを使用すべきではないのですか?
ジョナス

@Jonas:それもいいユースケースです!おそらく、答えを少し更新して明確にすることが役立つでしょう。
スティーブンジュリス

9

get / setメソッドのペアの使用は、悲劇的な歴史的な設計上の欠陥です。プロパティを冗長かつ非効率的に実装する別の言語を考えることはできません。


1
本当ですが、これは質問のポイントにやや接線的であり、(本質的に)set / getメソッドとパブリックフィールドの選択を考えると、ある状況でフィールドを好む理由はありますか?他の言語が問題に対してより良い解決策を提供するということは、私には無関係のように思えます。
ジュール

5

パブリックフィールドは、本質的に複素数やポイントのような値型であるクラスには問題ないと思います。クラスは、Cスタイルの構造体のようにプリミティブ型をグループ化し、いくつかの演算子を定義するだけです。


2
java.awt.Point友人は少し悪夢です。
トムホーティン-タックライン

@ TomHawtin-tackline:問題Pointは、型の変数Point場所をカプセル化することになっているのか、変更可能な場所にエンティティのIDをカプセル化するのに曖昧だということです。概念的には、Point通過するコードは配列を通過するコードに非常に似ていると考えます。
supercat

を取得しPointて変更した場合、それが参照するオブジェクトが画面上で正常に更新されることを期待する必要がありますか?いいえ、問題Pointは可変であるということです。私たちは持っていたString/ StringBufferしかし、アイデアは介して取得していないようでした。/配列を渡すと同様の問題が発生します。
トムホーティン-タックライン

5

パブリック定数を定義することは依然として有用です。例えば

public static final int DAYS_IN_WEEK = 7;

ただし、可能な場合は列挙型を引き続き使用してください。例えば

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

単純な構造体クラスシミュレートするのにも役立ちます。とにかくすべてのフィールドが公開されている場合、すべてのフィールドにゲッターとセッターを作成する理由はありません。

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

しかし、Javaのような言語には構造体が存在しないと多くの人が主張するでしょう

1
@delnan:JavaBeansとほとんど同じですが、JavaBeansははるかに冗長であり、スレッドセーフではありません。JavaBeansの代わりに不変のPOJOを使用してはならない理由を
ジョナス

いくつかのAndroid固有の観察:Enumはintよりも評価が遅く、避ける必要があります。また、タイトループ内でセッターとゲッターが頻繁にアクセスするフィールドも、パブリックであることの恩恵を受けることができます。
ネイラー

2

IDEが普及する前に、すべてのフィールドを公開することは、プロトタイプ/概念の証明をすばやく作成するための強力なツールでした。

最近では、マウスをクリックするだけでゲッター/セッターのペアを生成できる場合、それらを使用するための非常に小さな言い訳があります。


4
ただし、10個のpublic finalフィールドは10個のgetXXX()メソッドよりも読みやすくなっています。
ジョナス

1
@ジョナスはい、しかしここで最終的なフィールドについては話していない。パブリック最終フィールドも静的である場合、定数であり、constキーワードで十分です。静的でない場合、カプセル化の重大な違反となります。
-biziclop

3
@biziclop ウィキペディア:「Javaでキーワードとして予約が、CONSTを用いるとは機能がありませんされていない」
アビ亜麻

@Avi Flaxええ、ただし、定数をマークするために使用できたため、定数をパブリックフィールドとして宣言する必要がなくなりました。
-biziclop

2
ゲッター/セッターのペアが適切であると仮定すると、つまりです。それはしばしばそうではありません。
デビッドソーンリー

2

これは主観的なものですが、私の意見では、パブリック/プライベートの概念全体は時代遅れであり、逆になっています。

Pythonでは、パブリック/プライベートはありません。基本的にすべてが公開されています。多くの問題を引き起こしていません。

Javaでは、各フィールドに無意味なgetter / setterを作成して、「パブリック」とマークするという罪を避ける傾向があります。(あなたが自分でやっていることを見つけた場合は、単にそれらを公開する必要があります)。


Pythonでは、名前の前に__を付けることで、プライベートとしてマークすることができます。これらの変数やメソッドにアクセスする方法はまだあるため、100%プライベートではありませんが、C#ではリフレクションで同様のことができます。
アダムリア
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.