2
Public class Example {

    private int number;

    public Example(int number){
        this.number = number;
    }

    public int getNumber(){
        return number;
    }

    public void setNumber(int number){
        this.number = number;
    }

    public static void main(String[] args){
        Example e = new Example(5);

独自のクラス内の変数にアクセスするときに優先されるもの。「e.number」または「e.getNumber()」?

編集:
最も重要な質問は、呼び出したメソッドがゲッターまたはセッターであることをコンパイラが認識しているかどうかです。したがって、次のようe.setNumber(5);に高速になりますe.number = 5;

4

12 に答える 12

4

e.getNumber()が一般的なアプローチです。そうgetまたはset+ VariableName

こちらもご覧ください。

于 2010-05-19T11:40:49.953 に答える
3
this.number

ほとんどの場合、それらは同じコードに最適化されますが、セッター/ゲッターを使用するポイントは、実装の変更の場合に API の変更を避けることです。ただし、クラスでは「API」を使用しませんが、すべての内部と状態が表示されます。

さらに、使用できます

numer += 5;

それ以外の

setNumber(getNumber() + 5);

編集:もちろん、クラスの外では、内部表現を変更する可能性があり、新しい状態表現に関してそれらを再実装することで下位互換性を提供できるため、ゲッター/セッターによって保護する必要があります。

編集2main少し特別です。可能な限り最小限にする必要があると思いますmain-いくつかのオブジェクトを作成し、最大で1つまたは2つのメソッドを呼び出します-したがって、変数を割り当てるべきではなく、「外部」部分として脅かされるべきです。一方、main状態に直接アクセスする必要があるテストメソッドを提供するものもあります。したがって、可能であれば、のフィールドに直接アクセスしないでくださいmain

mainJVMを起動するとコストが相殺されるため、とにかく速度は問題ではありません。実際の違いは、JIT が処理する内部ループにあります。

于 2010-05-19T11:41:50.967 に答える
3

状況次第と言っていいでしょう。フィールドが のような単純なもので、将来変更される可能性が低いint場合は、 and notを使用してアクセスします。numbergetNumber()

フィールドが、何らかの状況でおそらく将来の状況で計算されるか、サブクラスでオーバーライドされる可能性のある、より複雑なものを表す場合getNumber()は、当然の選択です。

私の経験則:実行することで利益が得られる可能性がほとんどない場合はgetNumber()を使用しgetNumber()、そうでない場合numberは明確さと簡潔さのために を使用します。

于 2010-05-19T11:51:40.687 に答える
1

最後の質問に答えるには、次の例を見てください。

Java コード:

public void test2() {
    setNumber(getNumber() + 1);
}

バイトコード:

public test2()V
   L0
    LINENUMBER 47 L0
    ALOAD 0
    ALOAD 0
    INVOKEVIRTUAL com/test/ByteCodeTester.getNumber()I
    ICONST_1
    IADD
    INVOKEVIRTUAL com/test/ByteCodeTester.setNumber(I)V
   L1
    LINENUMBER 48 L1
    RETURN
   L2
    LOCALVARIABLE this Lcom/test/ByteCodeTester; L0 L2 0
    MAXSTACK = 3
    MAXLOCALS = 1

ご覧のとおり、バイトコードは引き続き 2 つのメソッド呼び出しを行います。したがって、この場合、コンパイラはそれを別の方法で処理しません。

于 2010-05-19T12:21:38.913 に答える
1

ゲッター/セッターが特別なことをした場合にのみ違いがあります。これが当てはまることが最初からわかっている場合は、クラス内でもメソッドを使用してください。そうでない場合は、直接フィールド操作を行い、必要に応じて後でリファクタリングを支援するために Eclipse に依存します。

于 2010-05-19T11:52:25.457 に答える
0

同じクラスで使用する場合は番号。そして、任意のサブクラスまたは外部のどこでも e.getnumber

于 2010-05-19T11:44:11.997 に答える
0

番号

例外番号は、基本クラスのプライベート メンバーです。次に、ゲッター/セッターを使用して明確にします。これは拡張クラスのメンバーではありません。

編集:ああ、クラス内のメイン関数でそれを使用することをメンターしますか? 次に、他の人が言ったように e.getNumber() をオフにします。

于 2010-05-19T11:41:04.580 に答える
0

public アクセサーが別の目的で存在する場合は、変数への一貫したアクセスを保証するため、このアクセサーを使用することをお勧めします。

ただし、変数にパブリック アクセサーがない場合は、変数に直接アクセスしても問題ないと見なされます。私はそれをプライベート変数に制限する傾向があります(つまり、コードにプライベートアクセサーはありませんが、基本クラスの実装でアクセスが必要な場合は、保護されたメンバーではなく保護されたアクセサーです)。

要約すると、必要なアクセサーだけがプライベートである場合を除いて、私は常にメンバーをプライベートに保ち、アクセサーを介してアクセスします。

于 2010-05-19T11:51:52.050 に答える
0

クラスに内部的にアクセスする場合でも、私は通常、セッター/ゲッターを通過することを好みます。

これを行うのは、getter を変更してプロパティ (遅延ロード変数など) を取得する以上のことを行う場合があるためです。クラスの他の部分を変更します。

とはいえ、例外もありますが、これらはほとんどの場合、一般的なベスト プラクティスよりも個人的な好みによるものです。メンバー変数に直接アクセスします。

  1. #equals()私が「低レベル」機能と見なすものを実装する場合 (これらは完全に主観的なものであり、私の場合、#hashCode()#toString()低レベル」と見なします)。これには非常に強力な技術的な理由があるとは思いません。単に「気分が良くなった」だけです。
  2. 他の誰かが指摘したように、セッター/ゲッターを使用するのがあまりにも不便な場合 (たとえば、num ++vs ))。setNumber(getNumber() + 1
  3. 私のゲッターが追加の作業を行う場合、そして私の特定のケースでは、その動作は望ましくありません。
  4. ...そして、おそらく私が見逃した他のケースがあります...
于 2010-05-19T11:55:56.690 に答える
0

this.number=.. を使用してマルチスレッドに別れを告げることは言うまでもありません。setNumber() を使用すると、Java はこのメソッドが最終的なものである可能性があり、最適化で多くのことを行うことができると結論付けているため、違いを感じることができません...

于 2010-05-19T12:10:25.823 に答える
0

ゲッター/セッターは、プライベート フィールドへのインターフェイスとして機能する以上のことを行うことが多いという点で優れています。返される/設定される値は、舞台裏で行われるより複雑な計算の一部である場合があります。

ただし、危険なのは、それらが本格的なメソッド呼び出しであるため、プロセスの開始、ファイルのダウンロード、高価なタスクの実行など、文字通り何でもできることです。これはもちろんゲッター/セッターのコンテキストからはばかげていますが、何かすることを避けるために。実際のメソッドを持たずに、ゲッター/セッターで行うべきことのほとんどを実行するコードについても聞いたことがあります!!

于 2010-05-19T12:19:13.473 に答える
0

JVM は、セッターのメソッド呼び出しを安全に実行できる場合はいつでも最適化します (つまり、フィールドをそのまま使用したくなるほとんどすべての場合)。したがって、パフォーマンスに関しては、JIT コンパイルを行わない JVM (Dalvik など) で実行している場合を除き、問題になりません。実際、メソッド呼び出しを何レベルも深く連鎖させることができ、JVM は実際にハードウェア上で実行するときにフィールド アクセスのみに最適化します。

そのため、getter/setter が本当に何か特別なことをしている場合を除いて (ここではそうではありません)、通常は getter/setter に関連するパフォーマンス コストについて心配する必要はありません。代わりに、他の基準に基づいて決定を下すことができます (基礎となる表現を柔軟に変更したいですか? 後のクラスで再定義したいですか? もしそうなら、再定義されたセッター/ゲッターは正しいですか、またはフィールドアクセスは正しいですか? ? など)。

于 2010-05-19T15:42:49.057 に答える