n1cef1sh's Blog

起因

在做课程大作业的时候要求使用java编程,菜鸡对于java的基础语法都掌握不好。过程中在使用某些变量或者方法时,IDE会提示将该变量/方法修改为static类型,虽然点一下就改好了,但是并不知道其中的原因,还是太辣鸡了,所以学习一下java中的static关键字。

学习

类的加载机制

首先复习一下两年前学习过的Java类的加载机制
类的生命周期包括这几个阶段

加载——验证——准备——解析——初始化——使用——卸载

其中两个关键阶段

static关键字

“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

也就是说:方便在没有创建对象的情况下来进行调用(方法/变量)。

  1. static方法
    对于静态方法来说,因为它不依附于任何对象,既然都没有对象,就谈不上this了。由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是在非静态成员方法中是可以访问静态成员方法/变量的。image.png

  2. static变量
    静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化。
    在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。

  3. static代码块
    tatic块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
    static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。所以可以将一些只需要进行一次的初始化操作都放在static代码块中进行。

练习1

package test;

public class Demo1 {
    Person person = new Person("demo1");
    static{
        System.out.println("demo1 static");
    }
     
    public Demo1() {
        System.out.println("demo1 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 Demo1 {
    Person person = new Person("MyClass");
    static{
        System.out.println("myclass static");
    }
     
    public MyClass() {
        System.out.println("myclass constructor");
    }
}

这段代码的输出会是什么?

image.png

练习2

package test;

public class Demo1 {
    
    static{
        System.out.println("test static 1");
    }
    public static void main(String[] args) {
         
    }
     
    static{
        System.out.println("test static 2");
    }
}

虽然主函数里并没有输出语句,但是加载Demo1类时会先执行static代码块,可以出现类中的任何地方(除了方法内部),并且执行是按照static块的顺序执行的。

image.png

小结

积累经验,搞清原理。不过有时候要抓紧主线,毕竟各种知识太庞杂了,不可能全都仔细研究学习,所以有的知识点只需要简单了解即可,先完成主线任务,不然就是浪费时间。

参考

http://www.cnblogs.com/dolphin0520/p/3799052.html
https://blog.csdn.net/weixin_44545800/article/details/109248633