Java 到底是什么?
![Java到底是什么?](https://static001.geekbang.org/infoq/bb/bb9d50312ee5ec751c7c42181d198ca3.png)
首先,Java 是我们常用的开发语言,但是它是跨平台使用的,所以在使用的过程中;
Java Virtual Machine Java 虚拟机,实现在虚拟机上运行
这里就出现一个问题:
1.JDK 和 JRE 以及 JVM 三者的关系:
JDK(Java Development kits):Java 开发工具包。
JRE(Java Runtime Environment):Java 运行环境。
JVM(Java Virtual Machine):Java 虚拟机。
JDK = JRE + 开发工具(javac.exe,java.exe,javadoc.exe 等)
JRE = JVM + 核心类库(常用类:String、日期时间、数学、集合、IO、网络、多线程等)
也就说,Java 源程序,经过 Javac.exe 的编译,然后进入到 jvm 的解释器中去运行,
![](https://static001.geekbang.org/infoq/4a/4ac3057a778e90b07c0e8ced4bfe00c2.png)
2.Java 打包成 Jar 供给项目部署:
Java 程序,一般在项目使用过程中,会打包中 Jar 包或者是 War 包
因为前后端分离的项目,所以前端一般都是 war 包,包含 web 端,后端一般是 Jar 包;
jar 就是多个 class 的二进制文件包(Java Archine)java 的归档文件
jar 包中的目录是怎样的:
![](https://static001.geekbang.org/infoq/e2/e241eca440eb9caa91273f3505687275.png)
meta-INF 是 maven 的打包的工具
org- 基于框架 spring,springboot 启动的一些二进制文件
boot-info 依赖的包,以及源代码的编译好的二进制文件.class 文件
![](https://static001.geekbang.org/infoq/86/8692ef1f47e4a0e38e6d49294187787b.png)
![](https://static001.geekbang.org/infoq/43/43108f92b3b814e40341cc48c16ca245.png)
![](https://static001.geekbang.org/infoq/db/db3f26f3c2612a592d076cdfa463d791.png)
3.加载到内存中后,jvm 会执行自己的字节码引擎,开始执行处理,
(需要哪个类,这个类就会加载),直至异常或者完成
![](https://static001.geekbang.org/infoq/bb/bb151d405d8c80e866dac60ce7c0ffa6.png)
课后小问题:
4.Java 可以经过 Javac 编译成二进制的文件 class,要是反编译是不是就可以拿到代码了?
解答:
可以编译,就可以反编译,因为 Java 有反射机制,所以反编译自然而然就可以,但是 jar 包的反编译之后可能会失去泛型,注释等东西
我们已经了解因为 jvm 只处理二进制 class 的文件,所以源代码经过编译成为二进制的 class 的字节码文件后,加载到 jvm 中经过了什么?https://blog.csdn.net/qq_36522306/article/details/80584595
2.本此的主题就是类的加载过程中,jvm 做了什么
![](https://static001.geekbang.org/infoq/09/09cd98c93507e3f3e1ddd1a243bd4d88.png)
3.类什么时候会加载, 在 jvm 执行时,需要的时候,会加载进来;
加载
之后,会遇到几个过程,比如
1.1 加载此类:(根据类加载器实现类的加载)
1.2 验证-->准备-->解析
验证当前加载的 class 字节码文件,是否合法,是否被篡改等,
准备,类加载之前,有开辟内存空间,加载静态成员变量(static 修饰的),初始话默认值即可,八种基础数据类型,引用类型就是 null
解析: 符号引用替换为直接引用(换成真正的内存引用)
![](https://static001.geekbang.org/infoq/03/03c57d5b89556e271e9eade21adc1f29.png)
1.3 初始化
这个阶段,一般是将类中的静态变量,静态代码块以及父子类的静态域加载
![](https://static001.geekbang.org/infoq/16/1685c0ddf1338b23e25d771cf05033bf.png)
比如我们要实例化一个对象,new Boy(),这个类会被先加载-->一系列进行类初始化,如果这个时候发现父类也没有加载,会优先加载和初始化父类,然后就会才会实例 new 出对象
![](https://static001.geekbang.org/infoq/3c/3c9fc42b687aba6df598828c7f64491c.png)
2.类加载器:
2.1 Bootstrap classloader (启动类加载器)
主要负责 Java 核心类,Java.lang 包等核心库中的类一般存放的位置在 JDK /lib 中
2.2 Extension ClassLoader(扩展类加载器)
java 安装目录中有一个 lib/ext 中的库 主要加载其中的这类;属于核心类库的一个拓展加载;
2.3 Application Classloader(应用程序类加载器):
主要是本地写好 Java 本地类,这个类加载器就是负责将自己写好的类加载到内存中;
2.4(自定义类加载器)根据自身需求去加载你的类
使用比较多就是关于一般是应用程序类加载器以及启动类加载器
这里我们引入一个新的概念--双亲委派机制,
3.双亲委派机制:
因为之前我了解过:本质: 需要加载类的时候,子类加载器优先会提前让父类加载器加载,是从下往上找,从上往下加载的过程,目的是为了防止重复加载,
![](https://static001.geekbang.org/infoq/70/70a5aeeb18ce83d32fbc0658795f5140.png)
如果是 jar 包人家反编译--很可能会获取到源代码,但是市面上现有有第三方的基于字节码的加密工具,可以考虑加密
版权声明: 本文为 InfoQ 作者【卢卡多多】的原创文章。
原文链接:【http://xie.infoq.cn/article/bac5e5cace03e4472cd942977】。文章转载请联系作者。
评论