Java中的对象变量与类变量

我正在学习Java,我不理解对象变量和类变量之间的区别。 我所知道的是,为了使它成为一个类变量,你必须先用静态语句声明它。 谢谢!

在Java(以及一般的OOP)中,对象有两种字段(变量)。

实例变量(或对象变量)是属于对象的特定实例的字段。

静态变量(或类变量)对同一个类的所有实例都是通用的。

这是一个例子:

public class Foobar{ static int counter = 0 ; //static variable..all instances of Foobar will share the same counter and will change if such is done public int id; //instance variable. Each instance has its own id public Foobar(){ this.id = counter++; } } 

用法:

 Foobar obj1 = new Foobar(); Foobar obj2 = new Foobar(); System.out.println("obj1 id : " + obj1.id + " obj2.id "+ obj2.id + " id count " + Foobar.counter); 

静态变量或类变量与实例变量或对象变量之间的区别非常简单。 您创建的每个对象都有自己的实例变量的副本。 如果类中有一个静态变量,那么所有对象只存在该静态变量的一个副本。 例如

 public class JellyBean{ // instance variables every jellyBean object will have its own // variable for color String color; // static variable only one copy of this variable exists for // all jellyBean objects. static int totalNumberOfJellyBeans; }//end class 

如果您创建了2个jellybean对象,那么Color将有两个变量,因为每个jellybean都有自己的颜色变量。 和totalNumberOfJellyBeans的1个变量,因为两个jellyBean对象都使用这个类变量。

对象变量是依赖于类的特定实例的状态,而类变量可通过类本身进行全局访问。 这可能有点模糊,所以这里有一些例子:

 class Muffin { private static final int calories = 9320; public String flavor; public Muffin( String flavor ){ this.flavor = flavor; } } 

在这个课程中, calories是一个类变量。 在任何其他代码中,您可以通过调用Muffin.calories获得任何松饼的卡路里数量。 在这种情况下, final关键字也用于使卡路里数量保持不变。

在同一个类中,我们有一个对象变量, flavor 。 这取决于类的实例,并在构造函数中设置。

 Muffin myMuffin = new Muffin( "blueberry" ); 

所以现在你可以通过调用myMuffin.flavor来访问这个特定的松饼的味道。 注意我们在访问它的flavor之前需要如何实例化Muffin对象。

更改静态(类)变量

上面的例子有点拉伸,因为不同类型的松饼会有不同的卡路里计数。 它们对常量很有用,但是这里静态变量的值发生了变化:

 class Muffin { private static int next_id = 1; public int id; public String flavor; public Muffin( String flavor ){ this.flavor = flavor; id = next_id++; } } 

在第二个例子中,我们需要为我们创建的每个松饼都有一个唯一的ID号,因此我们可以有一个静态变量,每次实例化Muffin时它都会增加。 static关键字使next_id的值在每次调用构造函数时next_id持久存在,因此id将不同并继续为每个新的松饼增加。

假设你有一辆名为ToyotaYaris的汽车蓝图,你可能会有一个名为maxSpeed的变量。 使用该蓝图制造的所有汽车(其实例)将具有相同的最大速度,因此该变量应该属于蓝图,而不是单个汽车。 如果maxSpeed在蓝图中发生变化,那么它将在它产生的所有汽车中发生变化。

但是,在每辆车上,您可能想要另一个名为speed变量。 此变量不属于蓝图,因为每辆车可以彼此独立地以不同的速度行驶,因此您需要该变量属于ToyotaYaris每个特定实例。

因此:

 class ToyotaYaris { static int maxSpeed; int speed; } 

对象变量或实例成员属于类的特定实例。 也就是说每个实例都有自己的数据副本。 类变量或静态成员由类的每个实例共享。 也就是说,无论有多少类实例,该数据只有一个副本。