static 关键字

static 静态的

static 可以修饰内部类(这里不讨论)

static 可以修饰属性 ====>> 静态变量

static 可以修饰方法 ====>> 静态方法

static 可以修饰代码块 ====>>静态代码块

  • static 修饰属性 ====>> 静态变量

 static可以修饰成员变量,不能修饰局部变量

public class Student {
    String stuID;
    String name;
    static String clsName;    //static 修饰成员变量
}
public class TestStudent {
  public static void main(String[] args) {
      Student s1 = new Student();
      s1.stuID="sg1524163";
      s1.name="刘备";
      s1.clsName="蜀国一班";//一处设置处处设置,一处修改处处修改!

      Student s2 = new Student();
      s2.stuID="sg16556163";
      s2.name="关羽";
      //s2.clsName="蜀国一班";

      Student s3 = new Student();
      s3.stuID="sg16657463";
      s3.name="张飞";
      //s3.clsName="蜀国一班";
    //当遇到很多对象都有同一个属性的值时,可用static修饰这个属性来减少赋值
      System.out.println(s1.name+"\t"+s1.clsName);
      System.out.println(s2.name+"\t"+s2.clsName);
      System.out.println(s3.name+"\t"+s3.clsName);
  }
}

输出结果:
刘备  蜀国一班
关羽  蜀国一班
张飞  蜀国一班

 需注意的问题

上面的例子中,是用对象(s1、s2、s3) 去调用静态属性(clsName) 的。--> clsName

但是,建议用去调用。--> Student.clsName 

当成员变量声明时使用了 static 关键字,那么这种变量称为静态变量,没有使用 static 关键字称为实例变量 

实例变量必须先创建对象,通过“引用”去访问,而静态变量访问时不需要创建对象,直接通过“类名”访问。

public class Phone {
    int memory;
    static String name;
}


//测试类
package test;
public class TestPhone {
    public static void main(String[] args) {
        Phone p1 = new Phone();
        p1.memory = 128;  //通过”引用“访问
        //p1.name = "红米";
        Phone.name = "红米";  //通过”类名“访问
        System.out.println("内存:"+p1.memory);
        System.out.println("品牌:"+Phone.name);
    }
}
输出结果:
  内存:128
  品牌:红米

 静态变量总结:

所有实例相关的,包括实例变量和实例方法,必须先创建对象,然后通过“引用”的方式去访问,如果空引用访问实例相关的成员,必然会出现空指针异常。所有静态相关的,包括静态变量和静态方法,直接使用“类名”去访问。虽然静态相关的成员也能使用“引用”去访问,但这种方式并不被主张。

  • static修饰方法 ====>> 静态方法

static关键字所修饰的方法就是静态方法。

比如我们import的util包,全是工具类!工具类所有的方法都是静态方法!

使用方法:类名 . 静态方法

下面,我们自定义一个工具类(所有方法用 static 修饰)

package cn.bjpowernode.javase01.day11.static02;

public class PrintUtil {
    //打印长方形
    public static void rect(int a,int b){
        for(int i=1;i<=a;i++){
            for(int j=1;j<=b;j++){
                System.out.print("* ");
            }
            System.out.println();
        }
    }
    //打印等腰三角形
    public static void triangle(int a){
        for(int i=1;i<=a;i++){
            for(int j=1;j<=(a-i);j++){
                System.out.print(" ");
            }
            for(int z=1;z<=(2*i-1);z++){
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

 创建测试类去调用上面的工具类(类名 . 静态方法

package cn.bjpowernode.javase01.day11.static02;

public class Test {
    public static void main(String[] args) {
        PrintUtil.rect(5,10);
        PrintUtil.triangle(5);
    }
}
//结果如下:

  • static 可以修饰代码块 ====>>静态代码块

先看格式:

在 { } 内,除了明显的死循环,其他内容都可以写,跟方法体没什么区别
但是,态代码块儿只能调用静态的成员,非静态代码块什么都能调用!

package test;
public class Student {
    String name;
    static  String clsName;    //静态变量

    public static void fun1(){   //静态方法
        System.out.println("fun1...");
    }
public void fun2(){   System.out.println("fun2...");  }
public Student() {  System.out.println("Student的构造函数...");  }
static{  System.out.println("Student的静态代码块。。。");  }
{  System.out.println(
"Student的非静态代码块...");  } }

 

创建测试类

package test;
public class TestStudent {
    public static void main(String[] args) {
        System.out.println("main....");
        Student s1 = new Student();
        Student s2 = new Student();
        System.out.println("姓名:"+s1.name);
        System.out.println("班级:"+Student.clsName);    //类.静态变量
        Student.fun1();    //类.静态方法
        s1.fun2();
    }

    static{  System.out.println("TestStudent的静态代码块。。。");  }

    {  System.out.println("TestStudent的非静态代码块...");  }
}
 1 执行结果:
 2     TestStudent的静态代码块。。。
 3     main....
 4     Student的静态代码块。。。
 5     Student的非静态代码块...
 6     Student的构造函数....
 7     Student的非静态代码块...
 8     Student的构造函数....
 9     姓名:null
10     班级:null
11     fun1...
12     fun2...

输出结果的解释如下:

一个类中有静态代码块、非静态代码块、构造函数时,如果创建对象,执行顺序:静态代码块 ==> 非静态代码块 ==> 构造函数

如下图:方法区中有个静态区,用来存放静态代码块、静态的变量、方法;而堆区就存放非静态的。

    当运行TestStudent 类时,

      第一步:编译把 *.java 文件变成 *.class 文件
      第二步:类加载( ClassLoader ),把代码片段加载到 jvm 虚拟机的方法区!
      类加载如果遇到静态代码块,直接执行!所以输出行2(仅一次)

      当创建了对象s1,就会加载Student类,在堆中开辟0x112位置,所以输出行4(仅一次)、5、6

      当创建了对象s2,在堆中开辟0x234位置,所以输出行7(同5)、8(同6)

      即,如果多次创建对象,非静态代码块和构造函数执行多次,静态代码块只执行一次!

      静态代码块只在类加载时执行,而类加载只会加载一次!
      第三步:执行程序

 

jvm打开,执行程序,jvm关闭!

 

posted @ 2022-03-11 14:00  鹿先森JIAN  阅读(207)  评论(0编辑  收藏  举报