关键字static与类的初始化

1、static关键字基本概念

方便在没有创建对象的情况下来进行调用。

即被static关键字修饰的不需要创建对象去调用,直接根据类名就可以去访问。

static关键字修饰类(内部类)

java里面static一般用来修饰成员变量或函数。但有一种特殊用法是用static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以。

public class StaticClass {
    public static class InnerClass{
        InnerClass(){
            System.out.println("=========静态内部类===========");
        }
        public void InnerMethod(){
            System.out.println("=========静态内部方法===========");
        }
    }
    public static void main(String[] args){
        // 直接通过StaticTest类名访问静态内部类InnerClass
        InnerClass inner=new StaticClass.InnerClass();
        inner.InnerMethod();
    }
}

如果没有用static修饰InterClass,则只能new 一个外部类实例。
再通过外部实例创建内部类。

public class StaticClass {
    public class InnerClass{
        InnerClass(){
            System.out.println("=========静态内部类===========");
        }
        public void InnerMethod(){
            System.out.println("=========静态内部方法===========");
        }
    }
    public static void main(String[] args){
        // new 一个外部类实例。再通过外部实例创建内部类。
        StaticClass classInner=new StaticClass();
        StaticClass.InnerClass inner=classInner.new InnerClass();
        inner.InnerMethod();
    }
}

static关键字修饰方法

修饰方法的时候,其实跟类一样,可以直接通过类名来进行调用:

public class StaticMethod {
    public static void test(){
        System.out.println("======静态方法======");
    }
    public static void main(String [] args){
        // 方式一:直接通过类名
//        StaticMethod.test();
        // 方式二:
        StaticMethod fdd=new StaticMethod();
        fdd.test();
    }
}

static关键字修饰变量

被static修饰的成员变量叫做静态变量,也叫做类变量,说明这个变量是属于这个类的,而不是属于是对象,没有被static修饰的成员变量叫做实例变量,说明这个变量是属于某个具体的对象的。

static关键字修饰代码块

父类静态变量--父类静态代码块--子类静态变量--子类静态代码块--父类普通变量--父类普通代码块--父类构造函数--子类普通变量--子类普通代码块--子类构造函数

public class Father {
    static{
        System.out.println("Father static");
    }
    public Father(){
        System.out.println("Father Constructor");
    }
}
public class Son  extends Father{
    static{
        System.out.println("Son static");
    }
    public Son(){
        System.out.println("Son Constructor");
    }
    public static void main(String [] args){
        new Son();
    }
}
// 输出:
Father static
Son static
Father Constructor
Son Constructor

静态对象的执行级别是一样的,因此会从最靠上的静态对象开始执行,而且每个静态方法只会在类生命的时候初始化一次。

类的初始化

静态代码块或者静态变量是对象加载的时候进行,且只加载一次。而成员变量或者普通代码块 每次实例的时候都会执行一次,而且都优先于构造方法。

public class ParentClass {
    //    父类静态成员
    static int num = 0;// 1
    String name = "qqqqqq";//4
    static String name2 = "wwwwwwwwwww";//2
    {
        System.out.println("name1:" + name);//5
        System.out.println("这里是块1============");
    }
    ParentClass(){
        System.out.println("这里是构造函数*************");//6
    }
    static {
        num += 1;
        System.out.println("name2:" + name2);
        System.out.println("这里是静态初始化块*************" + num);
    }
    static ParentClass parentClass = new ParentClass();//每次实例化一个对象,都需要进行类的初始化
}
public class TestClass {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ParentClass pa = new ParentClass();

    }
}
输出:
name2:wwwwwwwwwww
这里是静态初始化块*************1
name1:qqqqqq
这里是块1============
这里是构造函数*************
name1:qqqqqq
这里是块1============
这里是构造函数*************

2.基于上例,理解下类的初始化

1)类的加载:

JVM: Java Virtual Machine(Java虚拟机

引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

代表jvm将java文件编译成class文件后,以二进制流的方式存放到运行时数据的方法区中,并在java的堆中创建一个java.lang.Class对象,用来指向存放在方法堆中的数据结构。

2) 类的初始化:

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中验证、准备、解析3个部分统称为连接。类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。

3) 类加载有三种方式:

1、命令行启动应用时候由JVM初始化加载

2、通过Class.forName()方法动态加载

3、通过ClassLoader.loadClass()方法动态加载

初晨暖阳,夜落星河。 少年披梦,远方有歌。 红黄之上,春夏晚风。 闲肆游走,人群熙攘。
原文地址:https://www.cnblogs.com/alidata/p/13448621.html