1

Javaで足を濡らしているだけなので、これが少しナイーブに思える場合はお詫びします。実際にインスタンス/メンバー変数にアクセスするための規則をよりよく理解しようとしています。

非静的インスタンス変数を非静的コンテキストから操作できますか?

たとえば、次のクラス定義を変更して、id変数とversion変数をインクリメントできるようにするにはどうすればよいでしょうか。

    class Foo {
    
        private int id;
        private int version;
        public String product;
        public String model;
    
        private Foo( ) {
    
            // Can these variables be accessed from a non-static context?
            id++;
            version++;
    
        }
        ...

静的フィールドと比較して...

      class Foo {

        private static int id;
        private static int version;
        public String product;
        public String model;

        private Foo( ) {

            id++;
            version++;

        }
        ...

        

最初の例..。


11
モデル1
ファースト

11 モデル
2 秒

2番目の例..。


11
モデル1
ファースト


22
モデル2

4

5 に答える 5

3

はクラスにバインドされているため、static-variableから にアクセスできます。そのため、 内でアクセスしても、 内と同じようにアクセスされます。non-static contextstatic variablesnon-static contextstatic context

例: -

MyClass obj = null;
obj.staticVar = 10;

NPE驚いたことに、静的変数はアクセス方法に関係なくアクセスされるため、上記のコードは をスローしませんclass name

したがって、obj.staticVar実際には に置き換えられMyClass.staticVarます。

しかし、その逆は正しくありません。non-static variableから にアクセスすることはできませんstatic contextreference静的なコンテキストでは、インスタンスに何も持っていないためです。また、そのクラスのインスタンスへの参照がなければ、インスタンス変数にアクセスできません。


とはいえ、できるからといって、それがいいアイデアだとは限らないことにも注意してください。static variablea の内部constructorまたは in anyを変更することnon-static contextterribleアイデアです。これらの変数に加えた変更は、そのクラスのすべてのインスタンスに反映されるためです。

むしろ、a を使用して変数static-initialization blockを初期化する必要があります。すべての変数を初期化するために、一度に実行されます。staticStatic initialization blockclass-loadingstatic

于 2012-11-14T19:32:04.473 に答える
2

これらの属性をクラスの変数として維持しようとしている場合はstatic、そうしないことを強くお勧めします。それらidversionフィールドは、そのオブジェクトとそれらを必要とするすべてのオブジェクトに対して、それらを管理する特定のクラスに入れる必要があります。

そうすれば、「IdManager」に newidとnew を要求versionし、それらを作成したオブジェクトに割り当てることができます。

あなたの質問に答えるために、staticフィールドは特定のクラスのすべてのインスタンスで共有されるため、変更はすべてのインスタンスに影響します。

于 2012-11-14T19:32:13.943 に答える
2

静的フィールドはインスタンス間で共有されます。

反対に、インスタンス フィールドは1 つの特定のインスタンス スコープに限定されます。

これが、2 番目のインスタンスからフィールドを取得したときにフィールドが「リセット」されたように見える理由を説明しています。

したがって、最初のインスタンスのフィールドをインクリメントするには、次のようないくつかのパブリック メソッドを提供します。

public void incrementId(){
  id++;
}

次の方法で要件を達成できるようにします。

fooOne.incrementId(); // id => 2

fooTwo.incrementId(); // id => 2
于 2012-11-14T19:34:16.957 に答える
1

あなたが実証したことは、実際には望ましい動作です。

最初の例では、インスタンス変数を宣言し、コンストラクターでそれらをインクリメントします。これは、インスタンスにのみ影響します

2番目の例では、静的/クラス変数を宣言し、コンストラクターでそれらをインクリメントします。クラスを2 回インスタンス化すると、コンストラクターの呼び出しごとにクラス変数がインクリメントされるため、それらが 2 回インクリメントされます

于 2012-11-14T19:36:01.773 に答える
0

あなたが本当に欲しいのはこのようなものだと思います

    private static int globalID;
    private int id;
    private static int version;
    public String product;
    public String model;

    private Foo( ) {

        this.id = globalID;
        globalID++;
        //...
      }
于 2012-11-14T19:33:27.017 に答える