static关键字

2020-07-07  本文已影响0人  布莱安托

由static关键字修饰的成员称为静态成员,该关键字可以用来修饰:

静态成员属于它所在的类,不同于类的实例成员,每一个对象实例都有一份自己的拷贝,静态成员在类中只有一份,被所有对象实例共享。

同时,静态成员的存储位置也不同,静态成员存储在方法区,实例成员则存储在栈中。

静态变量

定义一个类,类中包含一个静态变量和一个实例变量

class A {
    
    private static int i;
    private int j;
    
    public static setI(int i) {
        A.i = i;
    }
    
    public static getI() {
        return i;
    }
    
    public setJ(int j) {
        this.j = j;
    }
    
    public getJ() {
        return j;
    }
    
}

对于A类来说,每一个对象都有一个自己的j,但这个类的所有实例共享一个i。静态变量的初始化是在类的初始化过程中完成的,也就是说即使A类没有创建人和一个实例对象,i也存在。

举例说明一下:

public class StaticTest {
    public static main(String[] args) {
        
        A a1 = new A();
        A a2 = new A();
        
        a1.setI(1);
        a2.setI(2);
        
        a1.setJ(3)
        a2.setJ(4);
        
        System.out.println("a1.i = " + a1.getI());
        System.out.println("a2.i = " + a2.getI());
        System.out.println("a1.j = " + a1.getJ());
        System.out.println("a2.j = " + a2.getI());
        
    }
}

结果为:

a1.i = 2

a2.i = 2

a1.j = 3

a2.j = 4

其中,通过a1和a2均对i赋值,发现a1赋的值被a2所覆盖,可以得到a1实例与a2实例共享一份静态变量i。

静态变量可以通过类直接调用,也可以通过对象实例调用,但是一般不推荐。

当一个成员变量为静态的,其getter/setter方法也必须为静态的。

静态常量

静态常量是更加常见的使用方式,用staticfinal两个关键字修饰,可以直接使用类调用。

常用的静态常量有Math.PISystem.out等等

与静态成员变量不同的是,静态常量常常被声明为public,这是因为常量被声明为final,所以它的值不允许修改。

静态方法

静态方法是一种不能操作对象的方法,在静态方法中不能访问非静态的变量,同时也不能通过this来读取变量和调用方法。

类的对象可以调用静态方法,但是不推荐使用,因为静态方法返回的结果与对象本身并无关系。

有两种情况需要使用静态方法:

  1. 一个方法不需要访问对象状态,其所需参数都是现实提供的,例如:Math.abs
  2. 一个方法只需要访问类的静态域,例如:A.getI()

工厂方法

工厂方法是静态方法的一个常见用途,类可以通过静态的工厂方法创建对象,例如LocalDate.now()就是创建一个当前时间的LocalDate对象。

NumberFormat类也是用工厂方法来生成不同格式的格式化对象,例如:

NumberFormat currency = NumberFormat.getCurrencyInstance();
NumberFormat percent = NumberFormat.getPercentInstance();
double d = 0.1;
System.out.println(currency.format(d));
System.out.println(percent.format(d));
/*
 * 结果
 * $0.10
 * 10%
 */

工厂方法可以使用户只关心对应类的工厂,而不用关心类的具体实现,提高了系统的扩展性。

静态内部类

static关键字修饰的内部类称之为静态内部类。

静态内部类的创建不需要外部类的对象,直接通过new Outer.Inner()方式调用构造方法即可。

静态内部类的方法可以访问外部类的静态成员,不可以访问非静态成员。

静态内部类也有自己的字节码文件,文件名为Outer$Inner.class

上一篇下一篇

猜你喜欢

热点阅读