Java static关键字与static{}语句块

Java static关键字与static{}语句块目录直通车一、类的加载特性与时机1、 类加载的特性2、类加载的时机二、static的三个常用1、修饰成员变量2、修饰成员方法3、 静态块(static{})一、类的加载特性与时机在进入static之前,先补一下关于类的脑。1、 类加载的特性在JVM的生命周期里,每个类只会被加载一次。类加载的原则:延迟加载,能少加载就少加载,因为虚拟机的空…

大家好,又见面了,我是你们的朋友全栈君。

目录直通车

一、 类的加载特性与时机

1、 类加载的特性

2、 类加载的时机

二、 static的三个常用

1、 修饰成员变量

2、 修饰成员方法

3、 静态块(static{})


一、 类的加载特性与时机

在进入static之前,先补一下关于类的脑。

1、 类加载的特性

在JVM的生命周期里,每个类只会被加载一次。

类加载的原则:延迟加载,能少加载就少加载,因为虚拟机的空间是有限的。

2、 类加载的时机

1)第一次创建对象要加载类.

2)调用静态方法时要加载类,访问静态属性时会加载类。

3)加载子类时必定会先加载父类。

4)创建对象引用不加载类.

5) 子类调用父类的静态方法时

    (1)当子类没有覆盖父类的静态方法时,只加载父类,不加载子类

    (2)当子类有覆盖父类的静态方法时,既加载父类,又加载子类

6)访问静态常量,如果编译器可以计算出常量的值,则不会加载类,例如:public static final int a =123;否则会加载类,例如:public static final int a = math.PI。

二、 static的三个常用

1、 修饰成员变量

2、 修饰成员方法

同C++是一样的概念。但是在JVM里面,JVM也会划分一个暂称静态存储区,用于存放方法的定义。实际上从更大的角度而言,它存放的是各种类的定义,当我们通过new来生成对象时,会根据这里定义的类的定义去创建对象。

下面观察两段代码的输出结果,加了static和没有加static的区别:

public class Person {
    String name;

    int age;
    
    public String toString() {
        return "Name:" + name + ", Age:" + age;
    }
    
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zhangsan";
        p1.age = 10;
        Person p2 = new Person();
        p2.name = "lisi";
        p2.age = 12;
        System.out.println(p1);
        System.out.println(p2);
    }

    /**输出结果
     * Name:zhangsan, Age:10
     * Name:lisi, Age:12
     */
}
public class Person {
    String name;
    // 给age加上static
    static int age;
    /* 其余代码不变... */

    /**输出结果
     * Name:zhangsan, Age:12
     * Name:lisi, Age:12
     */
}

结论:通过运行结果,可以看到 age都为12,只保存了最后一次给age赋的值。这是为什么呢,在内存里面发生了什么?

Java static关键字与static{}语句块

给age属性加了static关键字之后,Person对象就不再拥有age属性了,age属性会统一交给Person类去管理,即多个Person对象只会对应一个age属性,一个对象如果对age属性做了改变,其他的对象都会受到影响。

3、 静态块(static{})

(1) static关键字还有一个比较关键的作用,用来形成静态代码块(static{}(即static块))以优化程序性能。

(2) static块可以置于类中的任何地方,类中可以有多个static块。

(3) 在类初次被加载的时候执行且仅会被执行一次(这是优化性能的原因!!!),会按照static块的顺序来执行每个static块,一般用来初始化静态变量和调用静态方法。

下面通过两段代码,说明 static{} 为什么能优化程序性能。

实例

/**
 * 每次调用isBornBoomer的时候
 * 都会生成startDate和birthDate两个对象,造成了空间浪费
 */
class Person{
    private Date birthDate;
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        Date startDate = Date.valueOf("1997");
        Date endDate = Date.valueOf("2019");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

 

/**
 * 这里使用了static块
 * 只需要进行一次的初始化操作
 * 节省内存空间,优化性能
 */
class Person{
    private Date birthDate;
    private static Date startDate,endDate;

    static{
        startDate = Date.valueOf("1997");
        endDate = Date.valueOf("2019");
    }
     
    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }
     
    boolean isBornBoomer() {
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

注意:强调一下static块是会按照顺序执行,与main入口函数无关。

static还有一个不常用的用途,叫做 static静态导包 有兴趣的朋友可以去了解一下。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/160518.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号