java中的static关键字

又到了读代码了解java知识的时间了。今天我们来了解下java中的static关键字,来看看它的作用和一些相关原理。

package com.xingshulin;

public class StaticTest {

    private String a = "I am a! ";
    private static String b = "I am b! ";

    // 构造函数
    public StaticTest() {
        System.out.println("I am constructor!");
    }

    // static代码块
    static {
        System.out.println("I am static block 1!");
//        System.out.println(a);
    }

    public static void main(String args[]) {
        // 生成StaticTest类的对象
        StaticTest st = new StaticTest();

        // 打印变量a
        System.out.println(st.a);

        // 打印变量b
        System.out.println(StaticTest.b);
        System.out.println(b);

        // 运行静态方法
        staticMethod();
        StaticTest.staticMethod();

        // 运行非静态方法
        st.nonStaticMethod();
    }

    // 静态方法
    public static void staticMethod() {
        System.out.println("I am static method!");
        //System.out.println(a);
    }

    // 实例方法(非静态方法)
    public void nonStaticMethod() {
        System.out.println("I am non static method");
        System.out.println(a);
        System.out.println(b);
    }

    // static代码块
    static {
        System.out.println("I am static block 2!");
    }

    private static String c;

    // static代码块
    static {
        System.out.println("I am static block " + c + "!");

    }

}

运行结果如下:

I am static block 1!
I am static block 2!
I am static block null!
I am constructor!
I am a! 
I am b! 
I am b! 
I am static method!
I am static method!
I am non static method
I am a! 
I am b! 

这段代码很简单,但是也足够说明static关键字的作用了。从上面的例子中我们可以看到static的三种表现形式:static变量、static方法、static代码块

static变量

在代码中的变量b和c就是static变量,有人会问了,那变量a是什么?其实变量a叫实例变量。它们的区别是变量a是在创建对象后分配的;而static变量b和c不同,static变量被所有对象共享,在内存中只有一个副本,是在类加载的过程中分配到JVM的方法区中。static变量可用类名直接访问,如代码:


image.png

在这里我们多说一下变量c,我们是没有给它赋初值的,但是并没有造成编译出错,而且在打印的时候发现它的值被自动置为了null(因为是String类型)。这说明static变量不像局部变量那样需要赋初值才能编译,我认为主要的原因应该是static变量在方法区分配,而局部变量在栈中分配,方法区的内存可以动态变化,而栈的大小在线程运行前就需要是已知的,所以局部变量必须有初值(此处留坑,不一定理解的对)

static方法

和static变量类似,static方法也不需要创建对象就可以被所有对象调用,并可直接通过类名调用。


image.png

也正是由于这个特性,static方法中不能包含this等和对象有关的关键字,更不能包含实例变量和实例方法,否则编译会出现问题:


image.png

但是也如上图所示,实例方法中却可以包含实例变量和static变量,原因很简单,就不赘述了。

static代码块

static关键字还有一个比较关键的作用就是用来形成static代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
从上面的代码结果来看,的确是在类加载的时候就进行了static块的运行,因为所有的代码块打印都在构造函数之前。


运行结果

而且和static方法一样,static代码块中不能包含this等和对象有关的关键字,更不能包含实例变量和实例方法,否则编译会出现问题:


image.png

你可能感兴趣的:(java中的static关键字)