简单了解java类的初始化以及类的实例化

 更新时间:2019年07月15日 10:29:28   作者:正号先生  
这篇文章主要介绍了简单了解java类的初始化以及类的实例化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

上一篇我们知道了一个类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载。
当初始化完成以后,一个类所有的类变量(被static修饰的变量)都被赋值。但是未被static修饰的成员变量又是何时被赋值的呢?

一个类何时会被初始化

一个类何时被初始化可以分为以下几类:

  • 1.创建类的实例(new)。
  • 2.访问某个类或接口的静态变量,或者对该静态变量赋值。
  • 3.调用类的静态方法。
  • 4.通过反射方式执行以上三种行为。
  • 5.初始化子类的时候,会触发父类的初始化。
  • 6.Java虚拟机启动时被标明为启动类的类。(有main方法的类)
  • 7.JDK 1.7开始提供的动态语言支持。(了解即可)

我们来说道说道第3点和第6点

我们平常在使用main方法和调用某个类的静态方法的时候,是不是发现,并不能直接调用静态方法和main方法所在类的非静态方法和非静态变量。

可是明明不是说了在调用静态方法和执行main方法的时候,所在的类已经被初始化了吗?

是的!在上一章节我们就说,类初始化的时候会按照我们编写代码的顺序为类变量(static修饰的变量)进行赋值。注意哦,此时这个类仅仅只有静态变量被正确赋值了哦。

public class People{
  private static String name ="lisi";
  private int age = 18;
  
  static{
    name ="zhangsan";
  }
}

如上述代码,在该类被初始化之后,首先按照代码顺序将类变量(被static修饰的变量)赋值。所以name被赋值"lishi",然后再将name赋值为 "zhangsan"。此时age并没有值,直接直接调用会报错。

一个类何时被实例化

上一个章节中,我们明白了加载->验证->准备->解析->初始化的具体细节。

当初始化完成后,一个类的静态变量被正确赋值。如果这个对象是被new出来的。那么在初始化完成之后会进入实例化阶段。

实例化的具体步骤为:

父类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行)->父类构造函数->子类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行)->子类构造方法()

注意哦!
如果这个类有父类不光是先实例化父类。整体流程如下:
1. 加载父类
1.1 为静态属性分配存储空间并赋初始值
1.2 执行静态初始化块和静态初始化语句(从上至下)
2. 加载子类
2.1 为静态属性分配存储空间
2.2 执行静态初始化块和静态初始化语句(从上至下)
3. 加载父类构造器
3.1 为实例属性分配存数空间并赋初始值
3.2 执行实例初始化块和实例初始化语句
3.3 执行构造器内容
4. 加载子类构造器
4.1 为实例属性分配存数空间并赋初始值
4.2 执行实例初始化块和实例初始化语句
4.3 执行构造器内容

实例化的内存模型

到这里,我们就非常的清楚为什么在静态方法中不能直接调用非静态的变量,因为此时的非静态变量并没有被赋值。

以前我在学习的时候,new一个对象出来大家总是在说,我们初始化了这个对象,然后balabala。。。

导致我对于初始化和实例化里的静态变量和非静态变量何时被赋值一直有点模糊。new一个对象出来准确的来说是进行了初始化和实例化两个步骤,这样应该就会清晰了很多。

初始化完成以后,类被存放在方法区,注意哦,此时并没有存放在堆内存中。

只有当对象实例化进入堆内存中以后才会对非静态变量进行初始化赋值。

总结

这下总算吧一个类的初始化和实例化的细节搞明白了,关于文中的方法区,堆内存等内容,下一节再具体分析。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java如何实现判断文件的真实类型

    java如何实现判断文件的真实类型

    本篇文章主要介绍了java如何实现判断文件的真实类型,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • SpringBoot框架中Mybatis-plus的简单使用操作汇总

    SpringBoot框架中Mybatis-plus的简单使用操作汇总

    这篇文章主要介绍了SpringBoot框架中Mybatis-plus的简单使用,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • 详解SpringMVC组件之HandlerMapping(二)

    详解SpringMVC组件之HandlerMapping(二)

    这篇文章主要介绍了详解SpringMVC组件之HandlerMapping(二),HandlerMapping组件是Spring MVC核心组件,用来根据请求的request查找对应的Handler,在Spring MVC中,有各式各样的Web请求,每个请求都需要一个对应的Handler来处理,需要的朋友可以参考下
    2023-08-08
  • 解决IDEA target文件夹越来越大的问题

    解决IDEA target文件夹越来越大的问题

    这篇文章主要介绍了解决IDEA target文件夹越来越大的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • springboot新建项目pom.xml文件第一行报错的解决

    springboot新建项目pom.xml文件第一行报错的解决

    这篇文章主要介绍了springboot新建项目pom.xml文件第一行报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • java查找文件夹下最新生成的文件的方法

    java查找文件夹下最新生成的文件的方法

    在本篇文章中我们给大家分享了关于java怎么查找文件夹下最新生成的文件的相关方法和知识点,有需要的朋友们参考下。
    2019-07-07
  • Java多线程 Producer and Consumer设计模式

    Java多线程 Producer and Consumer设计模式

    这篇文章主要介绍了Java多线程 Producer and Consumer设计模式,producer是生产者的意思:指生产数据的线程,consumer是消费者的意思,指的是使用数据的线程,下文围绕Producer及Consumer展开话题,需要的朋友可以参考一下
    2021-10-10
  • 一篇超详细的Spring Boot整合Mybatis文章

    一篇超详细的Spring Boot整合Mybatis文章

    大家都知道springboot搭建一个spring框架只需要秒秒钟。下面通过实例代码给大家介绍一下springboot与mybatis的完美融合,非常不错,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2021-07-07
  • 使用Java实现接口拦截器来监控接口的执行情况

    使用Java实现接口拦截器来监控接口的执行情况

    在排查问题的时候,由于没有对接口的执行情况,以及入参进行监控,所以排查起问题就特别费劲,今天我们就一起来写一个接口的拦截器来监控接口的执行情况吧
    2024-01-01
  • 使用Sentinel滑动窗口实现限流和降级

    使用Sentinel滑动窗口实现限流和降级

    Sentinel 是一个开源的高可用性、高扩展性的实时流量控制框架,它可以用于保护服务稳定性,防止系统因为流量过大而崩溃,这篇文章我们所介绍的是滑动窗口,它是 Sentinel 实现限流和降级的重要组件之一,感兴趣的同学跟着小编来看看吧
    2023-09-09

最新评论