IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java基础深究----类与对象 -> 正文阅读

[Java知识库]Java基础深究----类与对象

写在前面:这篇文章考究了大量的博文与国内外百科,以线性叙事方式解析内容,请按顺序耐心的读懂,如有疑论请不吝评论。不太适合初学者。

目录

类的编译

对象的声明

?对象的实例化

类的实例化

引用指向实例


?

public class AppObject {
    static{
        System.out.println("TT被类加载器加载");
    }
}
AppObject obj = new AppObject();

这是创建一个Java对象最基础的过程,

如果我们可以多停留一秒的思考,就会发现这一句编码,竟有4个组成部分:

通常我们只关注获取对象之后可以进行的事情,实际上在这一句Java代码中,做了十分多的事情。

不妨将这段编码的有效组成拓扑展开,可以得到3个过程:

  • 类的编译

public class AppObject {
    static{
        System.out.println("TT被类加载器加载");
    }
}
  • 对象的声明
AppObject obj;
  • ?对象的实例化
obj = new AppObject();

?具体的流程如下:

类的编译

public class AppObject {
    public AppObject() {
    }

    static {
        System.out.println("TT被类加载器加载");
    }
}

运行启动后,IDE首先会根据javac命令编译项目下所有的Java文件为.class文件,这是一种16进制的字节码文件,如果用文本编辑器打开查看,会发现开头的魔数是"cafe babe",这是可被JVM读取的通行证,如果用IDE查看,会发现生成了一个缺省的构造方法。?

这里值得一提的是,对于各种引用包括:对象、变量、方法等,目前阶段无法得知引用的具体存储地址,因此用符号引用暂时代替。

对象的声明

public static void main(String[] args) {
        AppObject obj;
    }

运行主程序,这时你是否认为,JVM在内存上已经开辟了一个空间,预留给后续实例与引用对象关联?

继续看.class文件:

会发现声明并没有被编译,实际上不难理解,所有语言最终都会被解释为机器语言,在机器语言中,声明引用会为其分配一块内存空间,用以后续指向其他地址,如果没有后续初始化,将会造成资源浪费,Java在编译这一步就做了一定的性能优化。?

?对象的实例化

对象的实例化包括两个部分:类的实例化,引用指向实例

obj = new AppObject();

类的实例化

new AppObject()

类的实例化是一个统称,实际上由很多过程组成,由JVM主要完成。

首先, 在委托JVM前,我们已有的数据就只有.class文件,即接口入参。

数据流:.class文件字节码->字节流

随后类加载器ClassLoader会根据环境变量加载.class文件,利用Java I/O技术,将文件中的字节码解析为字节流缓存在机器内存中,这一过程称之为:加载

数据流:字节流接受校验

在引入字节流进入JVM之前,字节码校验器会检查那些无法执行的明显有破坏性的操作。除了系统类之外,其他类都要被校验,这一过程称之为:验证

数据流:准入JVM字节流->机器语言

值得一提的是JVM并没有明确固定虚拟机类型,但在Oracle或JDK中委托的都是Hotspot虚拟机,HotSpot虚拟机最明显的特点就是随用随编译的特性。这是因为,Hotspot拥有解释器与JIT编译器(Just in time Complier)。

当准入JVM字节流接入解释器后,解释器会根据字节映射Map去解释字节内容,详解请参考博文:深入理解JVM之Java字节码(.class)文件详解 - 简书

内容包括很多,比较值得我们注意的是,对应上图:

  • 解释出类元信息,即将类的结构体缓存至MetaSpace,相同的类名有且只解释一次,静态变量赋默认值,值得一提的是静态常量赋值,这是因为静态常量是类元信息,且直接解释为存储地址并存储数值,不同于静态变量是指针变量,指针变量是存储地址,指向地址存储数值,解析前是符号引用,无法完成变量赋值
  • 解释出常量信息到常量池,这里说的常量是指形如封装类的默认值、自定义的常量数据等
  • 解释出方法元,即类结构体只是字段以某种结构组织起来,方法无法简单以字段组织,需要同类的结构体一样,根据方法名将结构体缓存至MetaSpace

以上的过程称之为:准备

随后,在内存上已经缓存有静态结构、具有值的静态数据后,将符号引用(见类的编译)变为直接引用,即引用变量赋值真实的物理地址。这个过程称之为:解析

数据流:机器语言(未解释)->机器语言(数据、指令、地址)

这时MetaSpace完成了直接引用,具有了物理意义上的数据结构,开始执行静态代码(指令:赋值、寻址等),这称之为:初始化

JIT编译器在运行时与JVM交互,当JIT编译器利用热点代码探测技术找到运行高频的代码,并将适当的字节码序列编译为本地机器代码。使用JIT编译器时,硬件可以执行本机代码,而不是让JVM重复解释相同的字节码序列,并导致翻译过程相对冗长。这样可以提高执行速度,除非方法执行频率较低。

引用指向实例

public static void main(String[] args) {
        AppObject obj;
        obj = new AppObject();
    }

引用就是寻址,寻址就用指针变量,所以obj实际上就是一个局部指针变量,并在JVM栈中开辟空间,当类初始化完成后,该地址的数值存入类元信息结构体的首地址,即完成了对象的实例化。

几个拓展的特性

反射对象

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 15:37:37  更:2021-12-23 15:38:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:23:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码