参考:Java从入门到精通 第五版 清华大学出版社
有时,在处理数据的时候需要两个类在同一内存区域中共享一个数据。比如说,在计算圆的面积这一类中需要使用PI这个常量,同样,在计算球的体积这一类中同样也要用到。没有必要去在两个类分别创建这一个常量PI,因为这样会使得系统把这两个在不同类中定义的同一常量分配到不同的内存空间。
为此,可将这个常量设置为静态的,这个常量在内存中是被共享的。 被声明为static的变量,常量和方法被称为静态成员,属于类所有,区别于个别对象,可在本类或者其他类中使用类名和“.”运算符调用静态成员。
其定义格式为:static 数据类型 变量名
看下面一段例子:
public class StaticTset{
final static double pi = 3.14;//定义静态常量
static int id; //定义静态变量
public static void method1() { //定义静态方法
//...
}
public void method2() {
System.out.println(StaticTset.pi); //调用
System.out.println(StaticTset.id); //调用
StaticTset.method1(); //调用
}
}
这里分别用类名.静态成员 调用
再看接着的下面一段,这里编译的话会报错,因为method3是一个静态方法,而在其中调用了非静态方法method2和关键字this,故报错。
public static method3(){
method2();
return this;
}
在java中对于静态方法有两点规定:
- 静态方法中不可以使用this关键字
- 在静态方法中不可以直接调用非静态方法
此外,方法中的局部变量也不能声明为static。
通过一段例子来理解这个static:
public class TransferProperty {
int i = 47; // 定义成员变量
public void call() { // 定义成员方法
System.out.println("调用call()方法");
for (i = 0; i < 3; i++) {
System.out.print(i + " ");
if (i == 2) {
System.out.println("\n");
}
}
}
public TransferProperty() { // 定义构造方法
}
public static void main(String[] args) {
TransferProperty t1 = new TransferProperty(); // 创建一个对象
TransferProperty t2 = new TransferProperty(); // 创建另一个对象
t2.i = 60; // 将类成员变量赋值为60
// 使用第一个对象调用类成员变量
System.out.println("第一个实例对象调用变量i的结果:" + t1.i++);
t1.call(); // 使用第一个对象调用类成员方法
// 使用第二个对象调用类成员变量
System.out.println("第二个实例对象调用变量i的结果:" + t2.i);
t2.call(); // 使用第二个对象调用类成员方法
}
}
//输出结果:
第一个实例对象调用变量i的结果:47
调用call()方法
0 1 2
第二个实例对象调用变量i的结果:60
调用call()方法
0 1 2
可以看到,对象t1和t2以及局部方法中的i是各自独立的,改变了t2的i值并不影响t1的i值,成员变量可以被其中任何一个对象改变,这是因为内存中两个对象指向不同的区域,。为了不发生这种情况,使用static关键字,即对象调用这个静态成员变量,其他不变,修改成员变量为:
static int i = 47
其输出结果就变为了:
第一个实例对象调用变量i的结果:60
调用call()方法
0 1 2
第二个实例对象调用变量i的结果:3
调用call()方法
0 1 2
可以看到,语句t2.i = 6修改了静态成员变量的值,这时两个对象指向的是同一块内存区域,故t1.i也发生了变化,同理局部变量i