Javaのオブジェクトのような構造


195

オブジェクトのような構造体を作成するJavaの方法に完全に反していますか?

class SomeData1 {
    public int x;
    public int y;
}

アクセサーとミューテーターがJavaに似ているクラスを見ることができます。

class SomeData2 {
    int getX();
    void setX(int x);

    int getY();
    void setY(int y);

    private int x;
    private int y;
}

最初の例のクラスは表記上便利です。

// a function in a class
public int f(SomeData1 d) {
    return (3 * d.x) / d.y;
}

これは便利ではありません。

// a function in a class
public int f(SomeData2 d) {
    return (3 * d.getX()) / d.getY();
}

9
パブリックの可変フィールドの代わりに、パブリックの不変フィールドまたはパッケージローカルの可変フィールドを検討してください。どちらも私見より良いでしょう。
Peter Lawrey、2010

ゲッターとセッターは醜い/冗長なものですが、Javaの心臓部のようなものです。それは簡潔ではない言語です。一方で、IDEがそれを行うので、決して入力しないでください。動的言語ではタイプを少なくする必要がありますが、タイプする必要があります(通常、IDEが役立つ場合があります)。
Dan Rosenstark、

皮肉なことに、OOにはカプセル化という点で長所がありますが、CPUとストレージの面で代償を払う必要があります。ガベージコレクターは(ほぼ完全に)オブジェクト参照をクリアする必要があるかどうかを心配する必要をなくします。現在の傾向は、Cのような構造体のオフヒープを採用することにより、全面的に進んでいます。これは、キャッシングタイプのソリューション、プロセス間通信、メモリを大量に消費する処理の高速化、GC o / hの低下に最適であり、データセットのストレージo / hの低下からも恩恵を受けることができます。あなたが何をしているのかわかっているなら、あなたはこの質問をするつもりはないでしょう...だからもう一度考えてください!
user924272 2014

@ user924272:Re「Cのような構造体のオフヒープを採用することにより、現在の傾向は一巡しています」。あなたはJavaでどのようにするでしょうか??? IMHO、これは... Javaはその年齢を示している地域である
ToolmakerSteve

@ToolmakerSteve-サークルが表示されています。私だけではありません。Azulのような企業は、一時停止のないガベージコレクションに熱心です。Javaは古いです。そうだね。不平を言うのではなく、弱点を見つけてそれについて何かをするエンジニア?彼らは尊敬に値する!+10からAzulへ:-)
user924272 '20

回答:


62

これは一般的に議論されるトピックです。オブジェクトにパブリックフィールドを作成することの欠点は、それに設定される値を制御できないことです。同じコードを使用する多くのプログラマーがいるグループプロジェクトでは、副作用を回避することが重要です。また、フィールドのオブジェクトのコピーを返すか、なんらかの方法で変換する方がよい場合もあります。テストでそのようなメソッドをモックすることができます。新しいクラスを作成すると、すべての可能なアクションが表示されない場合があります。それは防御的なプログラミングのようなものです-いつかゲッターとセッターが役立つかもしれません、そしてそれらを作成/使用するために多くのコストはかかりません。したがって、それらは時々役立ちます。

実際には、ほとんどのフィールドには単純なゲッターとセッターがあります。可能な解決策は次のようになります。

public property String foo;   
a->Foo = b->Foo;

更新:プロパティのサポートがJava 7に追加されることはほとんどありません。Groovy、Scalaなどの他のJVM言語は現在、この機能をサポートしています。-アレックスミラー


28
それは残念です、私はC#スタイルのプロパティが好きです(あなたが話しているように聞こえます)
Jon Onstott

2
したがって、オーバーロードを使用してください... private int _x; public void x(int value){_x = value; } public int x(){return _x; }
Gordon

12
私はを使用できることを好み=ます。私の意見では、コードがよりクリーンになります。
Svish

6
@ T-Bull:x2つの異なるsを2つ持つことができるからといって、それは良い考えにはなりません。私見、それは人間の読者による混乱につながる可能性があるため、貧弱な提案です。基本原則:読者にダブルテイクを行わせないでください。あなたが言っていることを明確にしてください-エンティティごとに異なる名前を使用してください。違いは単にアンダースコアを追加することです。エンティティを区別するために周囲の句読点に依存しないでください。
ToolmakerSteve 2014年

2
@ToolmakerSteve:その「混乱を招く可能性がある」というのは最も一般的であり、コーディングドグマ(コーディングスタイルとは対照的)の防御に関しては依然として最も弱い議論です。最も単純なことで混乱する人が常にいます。あなたはいつも誰かが起きて半週間かそこらの間コーディングして、そしてミスリードするコーディングスタイルを非難した後で間違いを犯したと不平を言う誰かを見つけるでしょう。私はそれを数えません。そのスタイルは有効で明白であり、名前空間をクリーンに保ちます。また、ここには異なるエンティティはありません。/one/エンティティとその周りの定型コードがあります。
T-Bull

290

Javaが「構造体」をサポートしている場合(動作がない場合)、クラスが本質的に「構造体」である場合、パブリックインスタンス変数を使用するのが適切であるというSun Javaコーディングガイドラインに精通していないJavaの人が多いようです。

ゲッターとセッターはまるでJavaの中心にあるかのように、Javaの方法であると人々は考える傾向があります。これはそうではありません。Sun Javaコーディングガイドラインに従って、適切な状況でパブリックインスタンス変数を使用する場合、実際には、不要なゲッターとセッターで乱雑にするよりも優れたコードを記述しています。

1999年以降のJavaコード規約

10.1インスタンスおよびクラス変数へのアクセスの提供

正当な理由がない限り、インスタンスまたはクラス変数をパブリックにしないでください。多くの場合、インスタンス変数は明示的に設定する必要はなく、メソッド呼び出しの副作用として発生することもあります。

適切なパブリックインスタンス変数の1つの例は、クラスが基本的にデータ構造であり、動作がない場合です。つまり、クラスの代わりに構造体を使用した場合(Javaがサポートする構造体の場合)、クラスのインスタンス変数をpublicにすることが適切です。

http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html#177

http://en.wikipedia.org/wiki/Plain_old_data_structure

http://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html#28


88
+1信頼できるソースを実際に持っているため。他のすべての答えは、人々が事実であるかのように意見を紡いでいる人々です。
ArtOfWarfare 2012年

1
getおよびsetメソッドを使用してプロパティにアクセスする業界標準の方法であるJava Beans仕様があります。概要については、en.wikipedia.org / wiki / JavaBeansを参照してください。
user924272 14

4
@ user924272:Java Beans仕様はこの回答にどのように関連していますか。この回答では、「パブリックインスタンス変数」の使用が適切な場合について説明しています。仕様がインスタンス変数をプロパティに自動的に変換する標準的な方法である場合(C#の場合)、それは適切かもしれません。しかし、そうではありませんよね?このようなマッピングを行うために、作成する必要があるボイラープレートのゲッターとセッターの名前を指定するだけです。
ToolmakerSteve 2014年

@ToolmakerSteve。これはJavaの質問です。また、この質問は、仕様が存在する一般的な問題を回避します。昔ながらの観点から見ると、フィールドミューテーションをデバッグするための標準的な方法がある場合は、セッターでブレークポイントを設定する方がはるかに簡単です。これはおそらく、現代のデバッガで廃止された、まだ私は、これは小規模なアプリケーションのために大丈夫ですが、それは大きなアプリケーションや大規模な組織のための本当の頭痛の種がある...クラスに直接「パンチ」のオブジェクト時に顔をしかめざるを得てる
user924272

223

本当に常識を使ってください。次のようなものがあれば:

public class ScreenCoord2D{
    public int x;
    public int y;
}

次に、それらをゲッターとセッターでラップしても意味がありません。他の方法では、x座標とy座標をピクセル全体に格納することは決してありません。ゲッターとセッターはあなたを遅くするだけです。

一方で、

public class BankAccount{
    public int balance;
}

将来のある時点でバランスを計算する方法を変更することができます。これは本当にゲッターとセッターを使うべきです。

ルールを曲げてもよいかどうかがわかるように、良い実践を行っている理由を知ることは常に望ましいことです。


3
私はこの回答に沿って、さらに、フィールドが互いに大胆に独立している限り、パブリックフィールドを持つクラスを作成できると言います。つまり、あるフィールドは別のフィールドに依存していません。これは、多くの場合、関数からの複数の戻り値、または極性座標で非常に役立ちます。{角度、長さ}一緒に移動しますが、本質的に相互に依存しません。
Spacen Jasset 2012年

@SpacenJasset:参考までに、あなたの例(複数の戻り値;極座標)がパブリックフィールドとゲッター/セッターを使用するかどうかにどのような影響があるかはわかりません。複数の戻り値の場合、おそらく呼び出し側は戻り値を取得するだけなので、逆効果になる可能性もあります。これは、パブリックゲッターとプライベートセッター(不変)を支持することを主張しています。これは、(x、y)オブジェクトから極座標を返す場合にも当てはまります。極座標の個々のコンポーネントへの変更は(x、y)に変換されるため、ACCUMULATIVE数学エラーを考慮してください。
ToolmakerSteve 2014年

@SpacenJasset:しかし、私はあなたの原則に同意します。
ToolmakerSteve 2014年

1
あなたは有効なポイントを持っていますが、ピクセルの事は確かピクセルがウィンドウ(単なる一例)以内であることは作るので、悪い例であるような気がしている誰かがやるかもしれない何かを、しかも、誰かが、画素を設定せ(-5, -5)ていない可能性があります良いアイデアです。:-)
ホースリー

50

可変性の問題に対処するには、xとyをfinalとして宣言します。例えば:

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

これらのフィールドに書き込もうとするコードを呼び出すと、「フィールドxは最終的に宣言されているため、割り当てることができません」というコンパイル時エラーが発生します。

クライアントコードは、あなたがあなたの投稿で説明した「簡単な」便利さを持つことができます

public class DataTest {
    public DataTest() {
        Data data1 = new Data(1, 5);
        Data data2 = new Data(2, 4);
        System.out.println(f(data1));
        System.out.println(f(data2));
    }

    public int f(Data d) {
        return (3 * d.x) / d.y;
    }

    public static void main(String[] args) {
        DataTest dataTest = new DataTest();
    }
}

3
ありがとう-便利で簡潔な回答。可変性を望まない場合に、フィールド構文の利点を得る方法を示します。
ToolmakerSteve 2014年

@ToolmakerSteve-フィードバックに感謝-とても感謝しています。
Brian

私は、構造体「インスタンス」として、最終的な分野で、最終的なクラスの最後のインスタンスを使用しようとしましたが、中にcase、このようなインスタンスフィールドを参照表現、私が得ましたCase expressions must be constant expressions。これを回避する方法は何ですか?ここでの慣用的な概念は何ですか?
n611x007 14

1
finalフィールドは、クラスが最初に使用されるときに初期化されるため、定数ではないオブジェクトへの参照です。コンパイラはオブジェクト参照の「値」を知ることができません。定数はコンパイル時に既知でなければなりません。
JohanTidén2014年

1
+1本当に重要な答え。不変クラスの有用性は、私の意見では過小評価できません。彼らの「ファイアアンドフォーゲット」セマンティクスは、特にマルチスレッド環境では、コードに関する推論をより簡単にします。この場合、同期せずにスレッド間で任意に共有できます。
TheOperator 2016年

11

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;

8

ちなみに、例として示した構造は、Javaベースクラスライブラリに既に存在していますjava.awt.Point。パブリックフィールドとしてxとy があります自分確認してください

自分が何をしているのかを知っていて、チームの他のメンバーがそれを知っている場合は、パブリックフィールドがあってもかまいません。ただし、スタック割り当ての構造体であるかのようにオブジェクトを使用する開発者に関連するバグのように頭痛の種となる可能性があるため、これに依存しないでください(Javaオブジェクトは常にコピーとしてではなく参照としてメソッドに送信されます)。


+1問題についての良い言及-結果がまだC構造体ではない方法。ただし、Javaオブジェクトについて常に参照によって発生する問題は、パブリックの書き込み可能なフィールド(OPの質問の本質-どの表現を使用するか)の代わりにセッターを作成しても改善されません。むしろ、どちらでもないことを支持する議論である。IMMUTABILITYの議論です。これはpublic final、ブライアンの回答のようにフィールドとして、またはパブリックゲッターを使用してパブリックセッターを使用せずに実行できます。つまり、フィールドを使用するかアクセサを使用するかは重要ではありません。
ToolmakerSteve 2014年

8

Re:aku、izb、John Topley ...

可変性の問題に注意してください...

ゲッター/セッターを省略することは賢明に思えるかもしれません。実際には問題ない場合もあります。ここに示されている提案されたパターンの実際の問題は、可変性です。

問題は、最終ではないパブリックフィールドを含むオブジェクト参照を渡した場合です。その参照を持つ他のものは、それらのフィールドを自由に変更できます。そのオブジェクトの状態を制御することはできなくなりました。(文字列が変更可能な場合はどうなるか考えてください。)

そのオブジェクトが別の内部状態の重要な部分である場合、それは悪くなります。内部実装を公開したところです。これを防ぐには、代わりにオブジェクトのコピーを返す必要があります。これは機能しますが、作成された大量の使い捨てコピーから大量のGC圧力を引き起こす可能性があります。

パブリックフィールドがある場合は、クラスを読み取り専用にすることを検討してください。フィールドをパラメーターとしてコンストラクターに追加し、フィールドをfinalにマークします。それ以外の場合は、内部状態を公開していないことを確認し、戻り値の新しいインスタンスを構築する必要がある場合は、過度に呼び出されないようにしてください。

参照:Joshua Blochによる「Effective Java」-アイテム#13:不変性を好む。

PS:また、最近のすべてのJVMでは、可能であればgetMethodが最適化され、フィールド読み取り命令が1つだけになることに注意してください。


12
ゲッター/セッターはこの問題をどのように解決しますか?まだ参照があり、操作との同期はありません。ゲッター/セッターはそれ自体で保護を提供しません。
he_the_great 2008年

1
ゲッターとセッターは、必要に応じて同期を提供できます。また、ゲッターとセッターは、指定されたよりもはるかに多くのことを期待しています。これに関係なく、同期の問題は依然として残っています。
user924272 2014

7

私はこれをいくつかのプロジェクトで試しました。理論上、ゲッターとセッターは意味的に無意味な残骸でコードを散らかし、他の言語は規約ベースのデータ非表示または責任の分割(pythonなど)でうまく機能しているようです。

他の人が上で述べたように、あなたが遭遇する2つの問題があり、それらは実際には修正できません:

  • Javaの世界のほぼすべての自動化ツールは、getter / setter規約に依存しています。他の人が指摘したように、JSPタグ、Spring構成、Eclipseツールなどです。ツールが期待するものと戦うことは、その非標準的な開始方法を見つけようとしてグーグルをトローリングする長いセッションのレシピです。春の豆。本当にトラブルの価値はありません。
  • 何百ものパブリック変数を使用してエレガントにコード化されたアプリケーションを作成すると、それらが不十分である状況が少なくとも1つ見つかります-不変性が絶対に必要な場合、または変数が設定されたときにイベントをトリガーする必要がある場合、またはスローしたい場合オブジェクトの状態を不快なものに設定するため、変数の変更に関する例外。その後、変数が直接参照されるすべての特別な方法でコードを乱雑にするという、アプリケーション内の1000の変数のうち3つの特別なアクセスフォームを使用するという、うっとうしい選択肢に悩まされます。

そして、これは完全に自己完結型のプライベートプロジェクトで作業する最良のシナリオです。すべてを公的にアクセス可能なライブラリにエクスポートすると、これらの問題はさらに大きくなります。

Javaは非常に冗長であり、これは魅力的なことです。しないでください。


公共の場の道を行くことの問題についての優れた議論。Javaの明確な欠点。C#からJavaに切り替える必要があるときに私を困らせる(Javaの不便さをここで学んだ)。
ToolmakerSteve 2014年

4

Javaの方法がOOの方法である場合、はい、パブリックフィールドを持つクラスを作成すると、オブジェクトが独自の内部状態を管理する必要があるという情報の非表示に関する原則が崩れます。(つまり、私は単に専門用語を吐いているだけではないので、情報を隠すことの利点は、クラスの内部動作がインターフェースの背後に隠されていることです-構造体クラスがフィールドの1つを保存するメカニズムを変更したいとします。おそらく戻って、クラスを使用するクラスを変更する必要があります...)

また、JavaBeanネーミングに準拠したクラスのサポートを利用することもできません。たとえば、式言語を使用して記述されたJavaServer Pageでクラスを使用することを決定した場合、問題が生じます。

JavaWorldの記事「ゲッターメソッドとセッターメソッドが悪である理由」の記事も、アクセサーメソッドとミューテーターメソッドを実装しない場合を検討する際に役立ちます。

小さなソリューションを作成していて、関係するコードの量を最小限にしたい場合、Javaの方法は正しい方法ではない可能性があります-それは常にあなたとあなたが解決しようとしている問題に依存していると思います。


1
記事「ゲッターメソッドとセッターメソッドが悪である理由」へのリンクの+1。ただし、パブリックフィールドとパブリックゲッター/セッターの両方が等しくJavaの方法ではないことを指摘した場合、答えはより明確になります。その記事で説明されているように、可能であれば、どちらも行わないでください。代わりに、インスタンスの内部表現をミラーリングするのではなく、クライアントに必要な作業に固有のメソッドを提供します。ただし、これは実際に尋ねられる質問(単純な「構造体」の場合に使用する)には対応していないため、developer.g、izb、およびBrianがより適切に回答します。
ToolmakerSteve 2014年

3

作成者がオブジェクトではなく構造体(またはデータシャトル)であることを作成者が知っていれば、そのタイプのコードに問題はありません。多くのJava開発者は、整形式のオブジェクト(java.lang.Objectのサブクラスだけでなく、特定のドメインの真のオブジェクト)とパイナップルの違いを見分けることができません。エルゴは、オブジェクトが必要なときに構造体を作成し、逆もまた同様です。


パイナップルは私を笑わせます:)
ギヨーム

しかし、この答えはその違いが何であるかについては何も言っていません。熟練していない開発者を悩ませても、それらの開発者がいつ構造体を作るのか、いつクラスを作るのかを知る助けにはなりません。
ToolmakerSteve 2014年

著者は違いを認識しているため、違いについては何も述べていません(構造体のようなエンティティとは何かを知っています)。著者は構造体の使用がオブジェクト指向言語で適切であるかどうかを尋ねています、そして私はそう言います(問題のドメインによって異なります)。オブジェクトが実際のドメインオブジェクトになるものについての質問である場合、あなたはあなたの立場に立つことができます引数。
luis.espinal 2014年

さらに、違いを知らないはずの非熟練開発者の唯一のタイプは、まだ学校にいる人でしょう。これは、リンクリストとハッシュテーブルの違いを知るなど、非常に基本的なものです。真の目的が何であるかを知らずに4年間のソフトウェア学位を取得して卒業した場合、その人はこのキャリアのためにカットされないか、彼/彼女は学校に戻って返金を要求する必要があります。私は真剣です。
luis.espinal 2014年

しかし、あなたの不満を満たすために私は答えを提供します(これは元の質問とはほとんど関係がなく、独自のスレッドに値します)。オブジェクトには動作があり、状態をカプセル化します。構造体にはありません。オブジェクトはステートマシンです。構造体は単にデータを集約するためのものです。より複雑な答えが必要な場合は、自由に新しい質問を作成して、私たちがそれについて詳しく説明することができます。
luis.espinal 2014年

2

パブリックフィールドアクセスの使用に関する問題は、ファクトリメソッドの代わりにnewを使用する場合と同じ問題です。後で気が変わった場合、既存のすべての呼び出し元が壊れます。したがって、APIの進化の観点からは、通常、弾丸を噛んでゲッター/セッターを使用することをお勧めします。

もう1つの方法は、たとえば内部データ構造として使用される内部静的クラスなど、クラスへのアクセスを強く制御する場合です。この場合、フィールドアクセスを使用する方が明確な場合があります。

ちなみに、e-bartekの主張では、プロパティサポートがJava 7に追加される可能性はIMOにはほとんどありません。


1
これは本当ですが、Javaを使用している場合は問題ありません。ワンクリックでコードベース全体をリファクタリングできるためです(Eclipse、Netbeans、おそらくVIMとEmacsも)。Groovyのような動的な友達の1つを選択した場合、単純なカプセル化でさえ何時間も何日も修正することができます。幸いにも、あなたに知らせるテストケースがあるでしょう...どれだけ多くのコードを修正しなければならないか。
Dan Rosenstark、2010年

2
もちろん、すべてのユーザーがコードベースにいると想定しますが、もちろんそうではないこともよくあります。多くの場合、独自のコードベースにある可能性のあるコードを変更することは、さまざまな非技術的な理由で不可能です。
Alex Miller

2

私はコードを簡略化するためにプライベート内部クラスを構築するときにこのパターンを頻繁に使用しますが、そのようなオブジェクトをパブリックAPIで公開することはお勧めしません。一般に、パブリックAPIのオブジェクトを不変にできる頻度が高いほど優れており、「構造体のような」オブジェクトを不変の方法で構築することはできません。

余談ですが、このオブジェクトをプライベート内部クラスとして作成していたとしても、オブジェクトを初期化するコードを簡略化するコンストラクターを提供します。使用可能なオブジェクトを取得するために3行のコードが必要になるのは、面倒なだけです。


2

非常に古い質問ですが、もう少し短い貢献をさせてください。Java 8ではラムダ式とメソッド参照が導入されました。ラムダ式は、単純なメソッド参照であり、「真の」本体を宣言しない場合があります。ただし、フィールドをメソッド参照に「変換」することはできません。したがって

stream.mapToInt(SomeData1::x)

合法ではありませんが

stream.mapToInt(SomeData2::getX)

です。


この場合、を使用できますがdata -> data.x、これはまだ妥当です
James Kraus

1

常に単純な構造体であり、ビヘイビアーをそれに関連付けたいとは思わないことがわかっていれば、害はありません。


1

これは、Java言語ではなく、オブジェクト指向デザインに関する質問です。通常、クラス内のデータ型を非表示にし、クラスAPIの一部であるメソッドのみを公開することをお勧めします。内部データ型を公開した場合、将来それらを変更することはできません。それらを非表示にする場合、ユーザーに対する唯一の義務は、メソッドの戻り値と引数の型です。


1

ここでは、5人の名前と年齢を入力するプログラムを作成し、選択ソート(年齢別)を実行します。構造として機能するクラス(Cプログラミング言語など)とメインクラスを使用して、完全な操作を実行しました。以下、私はコードを提供しています...

import java.io.*;

class NameList {
    String name;
    int age;
}

class StructNameAge {
    public static void main(String [] args) throws IOException {

        NameList nl[]=new NameList[5]; // Create new radix of the structure NameList into 'nl' object
        NameList temp=new NameList(); // Create a temporary object of the structure

        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

        /* Enter data into each radix of 'nl' object */

        for(int i=0; i<5; i++) {
            nl[i]=new NameList(); // Assign the structure into each radix

            System.out.print("Name: ");
            nl[i].name=br.readLine();

            System.out.print("Age: ");
            nl[i].age=Integer.parseInt(br.readLine());

            System.out.println();
        }

        /* Perform the sort (Selection Sort Method) */

        for(int i=0; i<4; i++) {
            for(int j=i+1; j<5; j++) {
                if(nl[i].age>nl[j].age) {
                    temp=nl[i];
                    nl[i]=nl[j];
                    nl[j]=temp;
                }
            }
        }

        /* Print each radix stored in 'nl' object */

        for(int i=0; i<5; i++)
            System.out.println(nl[i].name+" ("+nl[i].age+")");
    }
}

上記のコードはエラーなしでテスト済みです...コピーしてIDEに貼り付けてください。:)


0

Javaではメソッドを使用せずにパブリックフィールドを持つ単純なクラスを作成できますが、それでもクラスであり、クラスと同じように構文とメモリ割り当ての点で引き続き処理されます。Javaで構造体を実際に再現する方法はありません。


0

メソッドから複数の値を返す必要があるときに、このようなクラスを使用することがあります。もちろん、そのようなオブジェクトは寿命が短く、可視性が非常に限られているため、問題ありません。


0

ほとんどの場合と同様に、一般的なルールがあり、特定の状況があります。特定のオブジェクトがどのように使用されるかがわかるように、クローズドでキャプチャされたアプリケーションを実行している場合は、可視性や効率を優先するために、より多くの自由度を行使できます。自分の制御が及ばない他の人が公に使用するクラスを開発している場合は、getter / setterモデルに傾倒してください。すべてのものと同様に、常識を使用してください。パブリックで最初のラウンドを行い、後でそれらをゲッター/セッターに変更することはしばしば問題ありません。


0

アスペクト指向プログラミングでは、割り当てまたはフェッチをトラップし、それらにインターセプトロジックをアタッチできます。これは、問題を解決するための正しい方法です。(それらをパブリックにする必要があるか、保護する必要があるか、パッケージで保護する必要があるかという問題は直交しています。)

したがって、適切なアクセス修飾子を持つインターセプトされていないフィールドから始めます。プログラムの要件が大きくなるにつれて、ロジックをアタッチして検証したり、返されたオブジェクトのコピーを作成したりします。

ゲッター/セッターの哲学は、必要のない多数の単純なケースにコストを課します。

アスペクトスタイルがよりクリーンかどうかは、ある程度定性的です。クラスの変数だけを見て、ロジックを個別に表示するのは簡単だと思います。実際、Apect指向プログラミングの存在理由は、多くの懸念が横断的であり、クラス本体自体でそれらを区分化することが理想的ではないことです(ロギングは例です-すべてをログに記録したい場合、Javaは大量のゲッターを記述してそれらを同期させますが、AspectJではワンライナーを使用できます)。

IDEの問題は深刻な問題です。get / setから生じる読み取りと視覚的な汚染なので、それほどタイピングではありません。

注釈は一見するとアスペクト指向プログラミングに似ていますが、AspectJでのワイルドカードのような簡潔なポイントカット仕様とは対照的に、注釈を付加してポイントカットを徹底的に列挙する必要があります。

AspectJの認識により、動的言語に早く慣れるのを防ぐことができれば幸いです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.