在初学Java时,我们都会发现在main方法前有一个叫做static的关键字,那它到底是什么意思呢?下面我们就一起了解了解它。
静态字段
静态字段就是将一个字段(通俗点说就是类中的变量或常量)的前面加上static关键字。
class Test{
public final static double PI = 3.1415926;
public static int number = 100;
}
上面代码定义了一个静态常量PI和一个静态变量number。
如果将一个字段定义为静态的,那么有以下几个特点:
1)静态字段是属于它被定义的那个类的,哪个类定义的它,它就属于哪个类。当在一个方法中调用它时,只能通过它的类名来调用,而不能通过类的对象变量来调用。就比如在Math类中定义的静态字段PI,它就是通过Math类来引用的。例如:System.out.println(Math.PI); 将输出:3.141592653589793。
2)每个对象变量都有一个自己的非静态字段,比如下面代码中的number1和number2,虽然在类中只定义一个非静态字段number,但number1和number2都有自己的number,一个是100,一个是500.
public class Test {
public static void main(String[] args) {
Test01 number1 = new Test01();
Test01 number2 = new Test01();
number1.setNumber(100);
number2.setNumber(500);
System.out.println(number1.getNumber());
System.out.println(number2.getNumber());
}
}
class Test01 {
private int number;
public Test01() {
}//无参构造函数
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
输出:
100
500
说了非静态字段,再来看看静态字段,它只有自己本身,不会像非静态字段那样生成副本,使非静态变量在每个对象变量中都不尽相同。只要在一个地方使它发生了改变,就彻底改变了。下面看一个例子:
public class Test {
public static void main(String[] args) {
Test01 number1 = new Test01();
Test01 number2 = new Test01();
number1.setNumber(100);
number2.setNumber(500);
System.out.println(number1.getNumber());
System.out.println(number2.getNumber());
}
}
class Test01 {
private static int number;
public Test01() {
}//无参构造函数
public void setNumber(int number) {
Test01.number = number;
}
public int getNumber() {
return number;
}
}
输出:
500
500
上面的代码仅仅将number改成了静态的(),外加setNumber方法用了类名引用,输出全变成了500,说明静态字段number是类所有,而不是对象所有。
3.由于静态字段属于类,不属于对象,所以也叫类字段。事实上,静态字段的静态根本没什么实际意义。
静态常量
静态常量很常用,例如Math类中的PI和E,在System类中out也被声明为静态常量。
我们可以看看Math类和System类中的静态常量,如下图
- Math类中的静态常量:
- System类中的静态常量:
由于每个对象都可以修改公共字段(public声明的字段),所以最好不要有公共字段。然而,声明公共常量却没问题,因为它已经是不可更改的了。如果想在类的外部通过类访问到静态常量,应声明为公共字段常量。
静态方法
与静态字段类似,静态方法是不会在对象上执行的方法。例如:Math类中的pow方法就是一个静态方法。表达式
Math.pow(a,b);
会计算a的b次方,完成计算是,它并不使用任何Math对象。
静态方法是不能访问非静态实例字段的,因为它不能在对象上执行操作,假如可以,那它访问的是哪个对象的实例字段呢,就不得而知了。但静态方法可以访问静态字段,因为静态字段是属于类,而不是对象。
在下面两种情况下可以使用静态方法
- 方法不需要访问对象状态(例如:Math.pow)。
- 方法只需要要访问静态字段。