static关键字在Java中使用频率也是很高的,今天就来将它所有的作用做一个总结归纳
static关键字主要有两种作用:
第一,为某些特定的数据类型或者对象分配单一的存储空间,而与创建对象的个数无关。
第二,实现某个方法或者是属性与类而不是与对象关联起来也就是说,在不创建对象的情况下就可以直接调用方法或使用类的属性。
具体而言,static关键字主要有四种使用情况:成员变量、成员方法、代码块和内部类
1.static 成员变量
在Java中虽然没有全局变量的概念,但还是可以使用static关键字达到全局的效果。在Java中有两种类型的变量:用static修饰的静态变量和不用static修饰的实例变量。静态变量属于类,在内存中只有一份,所有实例都指向该内存单元,静态变量在所属类加载时就为其开辟好了空间,就可以开始使用。对静态变量的引用有两种方式:
“类 . 静态变量” 和 “对象 . 静态变量”
实例变量属于对象,只有对象被创建后,实例变量才会被分配空间,才可以使用,它在内存中有多个复制。只能使用“对象 . 实例变量”的方式来引用。
另外,不可以在方法中定义static变量。
2.static 成员方法
与变量类似,在Java中也有static修饰的静态方法和没使用static修饰的普通方法。静态方法属于类,不需要创建对象就可以被调用。普通方法属于对象,只用对象创建出来才可以调用。
static中不可以使用this和super关键字,也不可以调用非static的变量和方法,只能访问所属类的静态成员和静态方法。因为static方法属于类,同对象解绑,而在调用非static方法时无法给其传入一个对象。
static另一个重要的用途就是实现单例模式。单例模式的特点是该类只能有一个实例,为了实现这一功能,必须隐藏类的构造函数,即声明为private,外界就无法直接创建这个类的对象,只能通过该类提供的方法来获取类的对象,要达到这样的目的就只能把创建对象的方法声明为static
class Singleton{
private staitc Singleton instance == null;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance ;
}
}
使用public和static修饰的变量和方法本质上都会是全局的,若在static变量前使用private修饰,则表示这个变量可以在类的静态代码块或者其他的静态成员方法中使用,但不可以从其他类中直接通过类名来引用。
3.static 代码块
static代码块即静态代码块,在类中是独立于成员变量和成员函数的代码块,它不在任何一个方法体内,JVM在加载类时就会执行static代码块,如果有多个static代码块,就会按照顺序执行。static代码块经常会被用来初始化静态变量,而且只会被执行一次。
public class Test{
private static int a;
static {
Test.a = 4;
System.out.println(a);
System.out.println("static block is called");
}
public static void main(String[] args){
System.out.println(5);
}
执行结果:
4
static block is called
5
4.static 内部类
static内部类是被声明为static的内部类,它可以不依赖外部类实例对象而被实例化,而通常内部类则需要在外部类实例化后才能实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员变量和静态方法(包括私有类型)
另外注意,只有内部类才能被定义为static 。
引申:
(1)什么是:实例变量?局部变量?类变量?final变量?
实例变量:变量归对象所有,每当实例化一个对象时,都会创建一个副本并初始化,如果没有显示初始化,那么会初始化一个默认值。
局部变量:在方法中定义的变量,使用前必须初始化
类变量:用static可以修饰属性、变量归类所有,只要类被加载,这个变量就可以被使用。所有实例化对象共享类变量。
final变量:表示这个变量为常量不可被修改
(2)static与final结合使用表示什么意思?
在Java中,时常出现static与final结合使用,用来修饰成员变量和成员方法。
对于变量,若使用static final 修饰,则表示一旦赋值就不可以更改,并且可以通过类名访问。
对于方法,若使用static final 修饰,则表示该方法不可覆盖,并且可以通过类名访问