Static关键字
- static方法必须有函数体,所以不能被声明为抽象方法
public class StaticA
{
//This method requires a body instead of a semicolon
public static void fun1();
}
static方法与该类实例无关,不能使用this关键字
Error:(32, 28) java: 无法从静态上下文中引用非静态 变量 this
java中普通类不能声明为static,普通类只能声明为public final abstract
//Illegal modifier for the class StaticA; only public, abstract & final are permitted
public static class StaticA
{
}
类中Static成员什么情况下会被初始化
该类被加载时,也就是该类在第一次被使用时才加载
验证代码
MyInstance被实例化时会在控制台输出信息
public class MyInstance
{
public MyInstance()
{
System.out.println("init MyInstance");
}
}
MyClass拥有一个MyInstance的static成员,一个静态方法与构造函数
public class MyClass
{
public static MyInstance instance = new MyInstance();
public static void say()
{
System.out.println("say something");
}
public MyClass()
{
System.out.println("init MyClass");
}
}
Main函数:
直接调用静态方法say(),MyClass的静态成员会先被初始化,然后调用
public static void main(String[] args)
{
MyClass.say();
}
结果:
init MyInstance
say something
不使用MyClass类,类不会被加载,其静态成员也不会被初始化
public static void main(String[] args)
{
System.out.println("run before");
结果:
run before
}
MyClass类在第一次被使用时才加载,其静态成员被初始化
public static void main(String[] args)
{
System.out.println("run before");
MyClass.say();
结果:
run before
init MyInstance
say something
}
静态成员MyInstance的实例化优先于MyClass构造函数调用
public static void main(String[] args)
{
System.out.println("run before");
MyClass c = new MyClass();
结果:
run before
init MyInstance
init MyClass
}
内部静态类
要把类声明为static只有一种情况,就是静态内部类。
静态内部类使用场景一般是当外部类需要使用内部类,而内部类无需外部类资源,并且内部类可以单独创建的时候会考虑采用静态内部类的设计private static class
使用场景:懒汉单例模式
先看看饿汉式单例
public class Singleton{
//类加载时就初始化
private static final Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
public static void say()
{
System.out.println("say hello");
}
}
调用getInstance()或say()时instance都会被实例化,但如果希望调用say()时不实例化instance,getInstance()时才实例化这个单例,即懒汉式,instance就不能作为该类的直接静态成员呈现。
此时可借助内部类,内部类在编译时会视为另外一个类,即编译之后会生成另外一个innner.class的文件,也就是说只有在第一次使用该内部类的时候才会实例化该内部类的静态成员。
public class Singleton
{
private static class SingletonHolder
{
private static final Singleton INSTANCE = new Singleton();
}
private Singleton ()
{
System.out.println("init Singleton");
}
//该方被锁定不能被子类修改
public static final Singleton getInstance()
{
System.out.println("getInstance");
return SingletonHolder.INSTANCE;
}
public static void say()
{
System.out.println("say");
}
}
只有调用getInstance()方法时内部类SingletonHolder才会被加载,其静态成员INSTANCE才会被实例化,而直接调用静态方say()则就不会生成Singleton实例了。
- public static class
使用场景:Builder模式