static关键字

本文主要介绍了Java中static关键字的使用。static可修饰属性、方法、代码块和类,静态变量为对象所共有,静态方法可通过类名调用,静态代码块随类加载且只执行一次。还分析了static关键字的加载顺序,以具体代码输出为例进行了详细说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

static关键字

static关键字的含义

  static:静态的。
  static可以修饰属性、修饰方法、修饰类、修饰代码块。

static修饰属性

  static修饰属性,则我们称该属性为静态变量或类变量

  静态变量:静态变量是每个对象所共有的,当一个对象修改某个静态变量时,其余对象的相同静态变量也会被修改。

  static修饰属性的说明:
            ① 静态变量随着类的加载而加载。
            ② 静态变量的加载早于实例变量的加载。
            ③ 由于类只会加载一次,则静态变量在内存中也只存在一份。
            ④ 静态变量可以使用对象调用,也可以使用类调用。实例变量(即非static修饰的属性)只能通过对象调用。

public class TestDemo1 {
    public static void main(String[] args) {
        Chinese c1 = new Chinese("张三",26);
        Chinese c2 = new Chinese("李四",29);
        c1.nation = "中国";
        System.out.println(c1.nation);  //输出 中国
        System.out.println("*********************");
        System.out.println(c2.nation);  //输出 中国
        //我们并没有修改对象c2的 nation属性,结果却显示 中国。 这就是由于我们将nation声明为static的
        //则nation为每个对象所共有的。
    }
}

class Chinese{
    public String name;
    public int age;
    public static String nation;

    public Chinese(){

    }

    public Chinese(String name,int age){
        this.name = name;
        this.age = age;
    }
}

static修饰方法

  static修饰方法:
        ① 随着类的加载而加载,通过“类名.方法名”的方式去调用,同时也可以使用对象调用。
        ② 在静态方法中只能调用静态方法和静态属性
        ③ 非静态方法中可以调用静态方法和属性,也可以调用非静态方法和属性。
        ④ 在静态方法中,不能使用super、this关键字。(因为super是父类对象的引用,this是本类对象的引用,静态方法是随着类加载而加载的,早于对象的加载。)

static修饰代码块

  static修饰代码块:
         ① 静态代码块,随着类加载而加载且只执行一次。如果在类中声明了多个静态代码块,则按照先后声明的顺序执行。
        ② 静态代码块的执行要优先于非静态代码块的执行,静态代码块只能调用静态属性和静态方法。

static修饰类:

  static修饰类只能作为内部类出现

  如何实例化静态内部类的对象?
      使用 new 外部类.内部类();

public class TestDemo1 {
    public static void main(String[] args) {
        Chinese c1 = new Chinese();
        // 实例化非静态内部类。 通过 外类对象.new 内部类();
        Chinese.XiAn x1 =c1.new XiAn();

        // 实例化静态内部类。通过 new 外部类.内部类();
        Chinese.JiangSu js = new Chinese.JiangSu();
        
        
        x1.introduce();
        js.told();

    }
}

class Chinese{
    public String name;
    public int age;
    public static String nation;

    class XiAn{
        public void introduce(){
            System.out.println("西安市");
        }
    }

    static class JiangSu{
        public void told(){
            System.out.println("江苏省");
        }
    }

    public Chinese(){

    }
}

关于static关键字加载顺序问题

public class Test {
    Person person = new Person("Test");
    static{
        System.out.println("test static");
    }

    public Test() {
        System.out.println("test constructor");
    }

    public static void main(String[] args) {
        new MyClass();
    }
}

class Person{
    static{
        System.out.println("person static");
    }
    public Person(String str) {
        System.out.println("person "+str);
    }
}


class MyClass extends Test {
    Person person = new Person("MyClass");
    static{
        System.out.println("myclass static");
    }

    public MyClass() {
        System.out.println("myclass constructor");
    }
}

  以上代码输出:
      test static
      myclass static
      person static
      person Test
      test Constructor
      person MyClass
      myclass constructor

  分析:
    ① 首先main函数是程序的入口,我们首先要加载包含main()的类Test。

    ② 加载类Test时,发现它有静态代码块,则先执行静态代码块: test static。

    ③ 紧接着,执行new Myclass();,创建Myclass的对象,则去加载Myclass类,在加载Myclass类时发现,Myclass类继承了Test类,则应先加载父类Test,之前已经加载过父类
Test了,所以不用再加载了。

    ④ 接着,发现子类Myclass中有静态代码块,则执行静态代码块: myclass static。

    ⑤ 接着,子类要想创建对象,则必须先加载完父类的成员变量和构造器,于是又去加载父类的成员变量: Person person = new Person(“Test”);

    ⑥ 此时发现 Person类还没有被加载,则加载Person类,发现Person类中有静态代码块,则加载静态代码块: person static。接着加载Person类构造器: person Test。

    ⑦ 加载完Person后,接着又返回来加载父类Test的构造器: test constructor。

    ⑧ 父类的成员变量和构造器加载完后,返回来加载子类的成员变量:Person person = new Person(“MyClass”); 则会输出: person Myclass,再接着加载子类的构造器,输出: myclass constructor;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值