static
表示静态的,可以用来修饰属性、方法、代码块、内部类
一、静态属性(类属性)
- 1、静态属性直接可以通过 类名.属性名 进行访问
- 2、静态属性也可以通过类的对象去调用,但这个静态属性在类的多个对象中是共享的
- (因为在创建对象时,静态域会将静态属性拷贝一份给每个对象)
public class MyClass {
static int num;
}
public class Test_MyClass {
public static void main(String[] args) {
//可直接通过 类名.属性名 进行访问
MyClass.num=10;
MyClass m1 = new MyClass();
m1.num=20;
System.out.println(m1.num);//num=20
MyClass m2 = new MyClass();
m2.num=30;
System.out.println(m2.num);//num=30
System.out.println(m1.num);//num=30
}
}
二、静态方法
- 1、静态方法可以直接通过 类名.方法名 进行访问
- 2、静态方法中只能访问静态方法,成员方法中可以直接调用静态方法
- 成员方法在类被创建的时候加载,静态方法在类加载的时候加载
- 3、静态方法中不能使用 this 和 super 关键字
- 4、静态方法不能被子类重写,但是可以被子类继承
public class MyClass {
static int num;
public static void m1() {
System.out.println("静态方法m1执行");
//this.num = 10;//这里使用this关键字会报错,super同理
}
public void m2() {
System.out.println("方法m2执行");
m1();//这里可直接调用静态方法
}
}
public class MyClass2 extends MyClass{
/* 重写报错
@Override
public static void m1() {
System.out.println("静态方法m1执行");
}
*/
@Override
public void m2() {
System.out.println("重写方法m2执行");
}
}
三、静态代码块
代码块:在类中使用 { } 包裹起来的代码片段
- 1、普通代码块的执行: 在类的对象被创建的时候执行,优先于构造方法先执行
- 2、静态代码块的执行: 在类加载的时候就执行,优先于普通代码块,但是静态代码块只会执行一次
package com.soder;
public class Soders {
static int p = 100;
{
System.out.println("父类代码块\t"+p);
}
static {
System.out.println("父类静态代码块\t"+p);
}
public Soders() {
System.out.println("父类构造方法\t"+p);
}
public static void m1() {
System.out.println("父类静态指令m1\t"+p);
}
public void m2() {
System.out.println("父类指令m2\t"+p);
}
}
package com.soder;
public class Soder1 extends Soders{
public Soder1() {
p--;
System.out.println("子类构造方法\t"+p);
}
{
System.out.println("子类代码块\t"+p);
}
static {
System.out.println("子类静态代码块\t"+p);
}
public static void m1() {
System.out.println("子类静态指令m1\t"+p);
}
public void m2() {
System.out.println("子类指令m2\t"+p);
}
}
package com.soder;
public class Test {
public static void main(String[] args) {
Soders s1 = new Soder1();
s1.m1(); //此处最好使用 Soders.m1(); 静态方法可以类名.方法名直接调用
s1.m2();
Soders.m1();
Soder1.m1();
}
}
运行结果
四、类加载
类加载的时机
- 1、创建对象的时候
- 2、子类被创建的时候
- 3、调用类中的静态属性或方法时
- 4、主动触发类加载 Class.forName(“全限定名”);即包名+类名,比如com.soder.Test
tips:当类被加载时,类的所有信息(包名,类名,属性,方法等)都会被加载到方法区,而其中的静态属性方法又会被调进静态域,可通过类名直接调用出来