前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java static关键字与static{}语句块

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

作者头像
全栈程序员站长
发布2022-09-09 10:59:14
4780
发布2022-09-09 10:59:14
举报
文章被收录于专栏:全栈程序员必看

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

目录直通车

一、 类的加载特性与时机

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的区别:

代码语言:javascript
复制
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
     */
}
代码语言:javascript
复制
public class Person {
    String name;
    // 给age加上static
    static int age;
    /* 其余代码不变... */

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

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

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

3、 静态块(static{})

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

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

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

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

实例

代码语言:javascript
复制
/**
 * 每次调用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;
    }
}
代码语言:javascript
复制
/**
 * 这里使用了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静态导包 。有兴趣的朋友可以去了解一下。

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 类的加载特性与时机
    • 1、 类加载的特性
      • 2、 类加载的时机
      • 二、 static的三个常用
        • 1、 修饰成员变量
          • 2、 修饰成员方法
            • 3、 静态块(static{})
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档