JAVA基础
static关键字
文章目录
- JAVA基础
- 概述
- 静态成员与加载顺序
概述
- static 变量:static变量由该类的所有对象共享,不需要创建对象也可使用。
- static 方法:允许直接访问,不需要创建对象也可被调用。如 main 方法。
- static 初始化块:在创建类的第一个对象前自动执行(先执行静态初始化块,再执行初始化块)。
- static 内部类:外部类对象共享,只能访问外部类的静态成员。
静态成员(字段和方法)属于类本身,而非类的实例。因此,可以通过类名直接访问和调用静态成员,无需创建对象。静态成员在内存中只有一份拷贝,被所有对象所共享。
另外,静态成员不依赖于对象的创建而存在,所以它们可以在没有创建对象的情况下被访问。然而,静态成员不能访问非静态成员,因为非静态成员需要通过对象才能够访问。
静态成员与加载顺序
public class FatherClass {
// static
public static String STATIC_FIELD = "father static field";
static {
System.out.println("father static block");
}
{
System.out.println("father non static block");
}
public FatherClass() {
System.out.println("father class construction");
}
public static void staticMethod() {
System.out.println("father static method");
}
// 内部类
public static class StaticInnerClass {
static {
System.out.println("FatherClass.StaticInnerClass static block");
}
{
System.out.println("FatherClass.StaticInnerClass non static block");
}
public StaticInnerClass() {
System.out.println("FatherClass.StaticInnerClass class construction");
}
public static void fatherStaticInnerClassStaticMethod() {
System.out.println("FatherClass.StaticInnerClass static method");
}
}
}
public class ChildClass extends FatherClass {
public static String STATIC_FIELD = "child static field";
static {
System.out.println("child static block 1");
}
{
System.out.println("child non static block 1");
}
static {
System.out.println("child static block 2");
}
{
System.out.println("child non static block 2");
}
public ChildClass() {
System.out.println("child class construction");
}
public static void staticMethod() {
System.out.println("child static method");
}
// 内部类
public static class StaticInnerClass {
static {
System.out.println("ChildClass.StaticInnerClass static block");
}
{
System.out.println("ChildClass.StaticInnerClass non static block");
}
public StaticInnerClass() {
System.out.println("ChildClass.StaticInnerClass class construction");
}
public static void childStaticInnerClassStaticMethod() {
System.out.println("ChildClass.StaticInnerClass static method");
}
}
/**
* 类初始化
* 1)静态变量(代码块)static只会初始化(执行)一次。
* 2)当有父类时,完整的初始化顺序为:父类静态变量(静态代码块)->子类静态变量(静态代码块)->父类非静态变量(非静态代码块) ->父类构造器 ->子类非静态变量(非静态代码块)->子类构造器 。
* 3)当有多个代码块时,按顺序加载.
* <p>
* father static block
* child static block 1
* child static block 2
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test start
* test end
*/
@Test
public void testInit() {
System.out.println("test start");
System.out.println("test end");
}
/**
* father static block
* child static block 1
* child static block 2
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test start
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test end
*/
@Test
public void testNewObj() {
System.out.println("test start");
ChildClass childClass = new ChildClass();
System.out.println("test end");
}
/**
* father static block
* child static block 1
* child static block 2
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test start
* FatherClass.StaticInnerClass static block
* ChildClass.StaticInnerClass static method
* test end
*/
@Test
public void testFatherStaticClass1() {
System.out.println("test start");
FatherClass.StaticInnerClass.fatherStaticInnerClassStaticMethod();
System.out.println("test end");
}
/**
* father static block
* child static block 1
* child static block 2
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test start
* FatherClass.StaticInnerClass static block
* FatherClass.StaticInnerClass non static block
* FatherClass.StaticInnerClass class construction
* ChildClass.StaticInnerClass static method
* test end
*/
@Test
public void testFatherStaticClass2() {
System.out.println("test start");
FatherClass.StaticInnerClass staticInnerClass = new FatherClass.StaticInnerClass();
staticInnerClass.fatherStaticInnerClassStaticMethod();
System.out.println("test end");
}
/**
* father static block
* child static block 1
* child static block 2
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test start
* ChildClass.StaticInnerClass static block
* ChildClass.StaticInnerClass static method
* test end
*/
@Test
public void testChildStaticClass1() {
System.out.println("test start");
ChildClass.StaticInnerClass.childStaticInnerClassStaticMethod();
System.out.println("test end");
}
/**
* father static block
* child static block 1
* child static block 2
* father non static block
* father class construction
* child non static block 1
* child non static block 2
* child class construction
* test start
* ChildClass.StaticInnerClass static block
* ChildClass.StaticInnerClass non static block
* ChildClass.StaticInnerClass class construction
* ChildClass.StaticInnerClass static method
* test end
*/
@Test
public void testChildStaticClass2() {
System.out.println("test start");
StaticInnerClass staticInnerClass = new StaticInnerClass();
staticInnerClass.childStaticInnerClassStaticMethod();
System.out.println("test end");
}
}