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静态导包 有兴趣的朋友可以去了解一下。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • wpf图表-Visifire使用教程分享

    wpf图表-Visifire使用教程分享visifire是一个基于WPF&silverlight的动画图表控件,支持数据绑定、数据钻取以及实时更新等功能特点。下面分享一些Visifire使用教程:Visifire图表控件对有大差异数据的图标绘制问题Visifire图表多线程技术Timer应用详解Visifire制作透明图表参考示例如何将Visifire所生成的图表转换成图片如何自定义visifire…

    2022年7月21日
    7
  • Git创建远程分支并提交代码到远程分支[通俗易懂]

    Git创建远程分支并提交代码到远程分支[通俗易懂]1、可以通过gitbranch-r命令查看远端库的分支情况如图所示,远程仓库只有一个master分支2、从已有的分支创建新的分支(如从master分支),创建一个dev分支但此时并没有在远程仓库上创建分支如图所示还是只有一个master分支3、建立本地到远端仓库的链接–这样代码才能提交上去使用命令行gitpush–set-…

    2022年6月30日
    19
  • 前端框架bootstrap和layui有什么区别

    前端框架bootstrap和layui有什么区别做前端的小伙伴肯定都用过或听过Bootstrap和LayUi,小编我虽然不是专业的前端程序员,但是对于前端还是颇有研究,闲暇事情会经常研究各种前端框架的源码,一来可以借鉴优秀框架的思想,二来可以顺便学习可以提高自己,好了,不废话了。web前端全栈资料粉丝福利(面试题、视频、资料笔记、进阶路线)先看百度Bootstrap的定义Bootstrap是美国Twitter公司的设计师MarkOtto和JacobThornton合作基于HTML、CSS、JavaScript开发的简洁、直观、强悍的前端

    2022年6月25日
    43
  • RabbitMQ的优先级队列「建议收藏」

    RabbitMQ的优先级队列「建议收藏」优先级队列队列需要设置优先级队列,消息需要设置消息的优先级。消费者需要等待消息已经发送到队列中,然后对队列中的消息进行排序,最后再去消费。Map<String,Object>arguments=newHashMap<>();arguments.put(“x-max-priority”,10);//设置优先级队列channel.queueDeclare(QUEUE_NAME,false,false,fal

    2022年9月23日
    0
  • MapReduce 编程不可怕,一篇文章搞定它

    MapReduce 编程不可怕,一篇文章搞定它前言本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!本专栏目录结构和参考文献请见1000个问题搞定大数据技术体系正文需求:WordCount,大数据领域的HelloWorld。Mapperpackagecom.shockang.study.bigdata.mapreduce;importjava.io.IOException;importorg.apache.hadoop.io.IntWr

    2022年6月14日
    28
  • 数据结构的堆排序_数据结构冒泡排序算法

    数据结构的堆排序_数据结构冒泡排序算法一、什么是堆排序1.堆,堆排序对于“堆”我们可以理解为具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆堆

    2022年8月16日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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