web-dev-qa-db-ja.com

Javaのクラス変数とインスタンス変数の違いは何ですか?

私はJavaに慣れていないので、クラス変数とインスタンス変数の違いを理解したいと思っています。

例えば:

class Bicycle { 
    static int cadence = 0; 
    int speed = 0; 
    int gear = 1; 
}

インスタンス変数とクラス変数はどのように違うのですか?ここでどの変数がクラス変数で、どれがインスタンス変数ですか?これはスコープにどのように影響しますか?

16
Skylar Adams

どちらもmember変数です。つまり、どちらもクラスに関連付けられています。もちろん、この2つには違いがあります。

インスタンス変数:

これらの変数はクラスのインスタンス、つまりオブジェクトに属しています。そして、そのクラス(オブジェクト)のすべてのインスタンスには、その変数の独自のコピーがあります。変数に加えられた変更は、そのクラスの他のインスタンスには反映されません。

public class Product {
    public int Barcode;
}

クラス変数:

これらは静的メンバー変数とも呼ばれ、そのクラスのすべてのインスタンスで共有される変数のコピーは1つだけです。その変数に変更が加えられた場合、他のすべてのインスタンスは変更の効果を確認します。

public class Product {
    public static int Barcode;
}

完全な例:

// INSTANCE VARIABLE
public class Main {

    public static void main(String[] args) {

        Product prod1 = new Product();
        prod1.Barcode = 123456;

        Product prod2 = new Product();
        prod2.Barcode = 987654;

        System.out.println(prod1.Barcode);
        System.out.println(prod2.Barcode);
    }
}

public class Product {
    public int Barcode;
}

出力は次のようになります。

123456

987654

次に、インスタンス変数を静的にして、クラス変数に変更します。

//CLASS VARIABLE
public class Main {

    public static void main(String[] args) {

        Product prod1 = new Product();
        prod1.setBarcode(123456);
        Product prod2 = new Product();
        prod2.setBarcode(987654);

        System.out.println(prod1.getBarcode());
        System.out.println(prod2.getBarcode());
    }
}

public class Product {

    public static int Barcode;

    public int getBarcode() {
        return Barcode;
    }

    public void setBarcode(int value){
        Barcode = value;
    }
}

非静的メソッドを使用してBarcodeの値を取得および設定し、クラスからではなくオブジェクトから呼び出すことができるようにしました。出力は次のようになります。

987654

987654

35
Abbas

説明は here (クラス変数Bicycleとインスタンス変数numberOfBicyclescadencespeedgearを含むidクラスの例):

すべてのオブジェクトに共通の変数が必要になる場合があります。これは、static修飾子を使用して行います。宣言にstatic修飾子を含むフィールドは、静的フィールドまたはクラス変数と呼ばれます。それらは、オブジェクトではなくクラスに関連付けられています。クラスのすべてのインスタンスは、メモリ内の1つの固定位置にあるクラス変数を共有します。どのオブジェクトでもクラス変数の値を変更できますが、クラスのインスタンスを作成せずにクラス変数を操作することもできます。

クラス変数(staticで宣言)は、すべてのインスタンスに共通の場所です。

この例では、numberOfBicyclesはクラス変数です(staticと宣言されているため)。すべてのインスタンスとクラスに共通するこのような変数(つまり、場所)は1つだけです。したがって、1つのメソッドでnumberOfBicyclesを変更すると、他のメソッドで新しい値が表示されます(異なるBicycleオブジェクトの場合でも)

対照的に、gearおよびidinstance変数です(それらの宣言にはstatic修飾子がないため)。すべてのBicycleオブジェクトには独自のオブジェクトがあります。一部のgearBicycleを変更する場合a、およびbが別の場合インスタンス、_a.gear_を変更しても_b.gear_には影響しません

各Javaオブジェクトは、いくつかのメタデータ(たとえば、そのクラスへの参照)と独自のインスタンス変数(おそらくスーパークラスから継承されたもの)を持つ別個のメモリゾーンです。ただし、クラス変数は、クラスであり、すべてのインスタンスで共有されます。

Object(computer science)Instance variable wikipagesも参照してください。

インスタンス変数:

  • インスタンス変数はクラス内で宣言されますが、メソッド、コンストラクター、または任意のブロックの外側です。
  • インスタンス変数はクラスのインスタンスに属しているか、インスタンス変数はオブジェクトに属していると言えます。
  • インスタンス変数には、クラスのインスタンスごとに個別の値があります。

    Class InstanceDemo {
    
         // this instance variable is visible for any child class.
           public String name = "Testing";
    
         // count variable is visible in Demo class only.
           private int count = 2;
    }
    

インスタンス変数にアクセスする方法:

InstanceDemo demo = new InstanceDemo ();

System.out.println("Access Instance variable: " + demo.count + " , "+demo.name );

出力: 2、テスト

クラス変数:

  • クラス変数はクラスに属しています。
  • クラス変数は、変数の前に「静的」キーワードを追加することによって作成されます。
  • 静的変数とも呼ばれます。
  • また、最も重要なクラス変数は、クラスのインスタンスオブジェクトが存在しない場合でも、クラスのすべてのインスタンスに対して単一の共有値を維持します。

        Class ClassDemo {
    
         // count variable is Same for all instance of this class
           public static int count = 2;
    }
    

クラス変数にアクセスする方法:

System.out.println("Access Class variable: " + ClassDemo.count );
//class variable is directly refer with class name

出力:2

クラス変数とインスタンス変数の簡単な違い:

  • インスタンス変数には、クラスのインスタンスごとに個別の値があります。クラス変数は、そのクラスのインスタンスオブジェクトが存在しない場合でも、クラスのすべてのインスタンスに対して単一の共有値を維持します。
  • Staticキーワードを使用して、インスタンス変数をクラス変数に変更します。
  • インスタンス変数とクラス変数はどちらも、メソッド内ではなく、クラスレベルで宣言されます。
4
Garg's

class variables変数とinstance変数の違いは、単にwho knows what?の問題です。

instance variableは、(=bound)だけがそのconcreteインスタンスに認識されているため、名前。

  public class Person {
       private String firstName;
       private String lastName;
  [...]
  }

クラスの定義は、concreteオブジェクトを構築するためのblueprintのようなものです。おそらく、この点は少し混乱します。しかし、このように書くと、すべての変数がその具体的なオブジェクトにバインドされます。 すべての人は独自の名を持っています

一方、class variableは-名前が示すように-クラスのすべてのメンバーに知られています。または技術的に:クラスレベルで既知/バインドされています。典型的な例は、作成したオブジェクトの数のカウンターです-これは非常に問題のある例ですが、しかし、それはこの初期段階では問題ではありません。

  public class Person {
       private String firstName;
       private String lastName;
  [...]
       static int numberOfPersons = 0
  }

numberOfPersonsstaticと宣言されています。これは、class variablesinstance variabesを区別するためのキーワードです。変数は、クラス定義内で他の変数と同様に宣言されています。しかし、staticキーワードは、それが異なることを示しています。

  • firstNamelastNameインスタンス変数であり、その具象インスタンスにバインドされています

  • numberOfPersonsはクラスにバインドされているため、すべてのインスタンスがこの変数にアクセスできます。

tl; dr

変数が定義されている場所はクラス定義です。

クラス変数は、クラスレベルで認識されているか、クラスレベルにバインドされています。つまり、各具象インスタンスはそれにアクセスできます。クラス変数を定義するには、キーワードstaticを使用します。

インスタンス変数はインスタンスレベルでのみ認識されます。 staticキーワードなしで定義します。

Javaの詳細なドキュメントは here です

3
Thomas Junk