简单说,Java字节码就是.class
后缀的文件,里面存放Java虚拟机执行的指令。
由于Java是一门跨平台的编译型语言,所以可以适用于不同平台,不同CPU的计算机,开发者只需要将自己的代码编译一次,就可以运行在不同平台的JVM中。
甚至,开发者可以用类似Scala、Kotlin这样的语言编写代码,只要你的编译器能够将代码编译成.class文
件,都可以在JVM虚拟机中运行:
uploading-image-878441.png
ClassLoader
是一个加载器,就是用来告诉JVM虚拟机如何去加载这个类,默认的就是根据类名来加载类,这个类名需要是完整路径,比如说java.lang.Runtime
URLClassLoader
实际上是我们平时默认使用的 AppClassLoader
的父类,所以,我们解释URLClassLoader
的工作过程实际上就是在解释默认的Java类加载器的工作流程
正常情况下,Java会根据配置项 sun.boot.class.path
和 java.class.path
中列举到的基础路径(这
些路径是经过处理后的 java.net.URL
类)来寻找.class
文件来加载,而这个基础路径有分为三种情况:
/
结尾,则认为是一个JAR文件,使用 JarLoader 来寻找类,即为在Jar包中寻找.class文件/
结尾,且协议名是 file ,则使用 FileLoader 来寻找类,即为在本地文件系统中寻找.class文件/
结尾,且协议名不是 file ,则使用最基础的 Loader 来寻找类使用Http协议测试,看Java是否能从远程HTTP服务器上加载.class
文件:
先编译一个.class
文件放在服务器上(这里用自己Python起个服务器,就是访问不到,气死)
public class Hello { public Evil() throws Exception { } }
其实,不管是加载远程class文件,还是本地的class或jar文件,Java都经历的是下面这三个方法调用
ClassLoader#loadClass ---> ClassLoader#findClass ---> ClassLoader#defineClass
loadClass
的作用是从已加载的类缓存、父加载器等位置寻找类(这里实际上是双亲委派机制),在前面没有找到的情况下,执行 findClass
findClass
的作用是根据基础URL指定的方式来加载类的字节码,就像上面说到的,可能会在defineClass
defineClass
的作用是处理前面传入的字节码,将其处理成真正的Java类所以真正核心的部分其实是 defineClass
,他决定了如何将一段字节流转变成一个Java类,Java
默认的 ClassLoader#defineClass
是一个native
方法,逻辑在JVM的C语言代码中
native方法称为本地方法。在java源程序中以关键字“native”声明,不提供函数体。
其实现使用C/C++语言在另外的文件中编写,编写的规则遵循Java本地接口的规范(简称JNI)。
简而言就是Java中声明的可调用的使用C/C++实现的方法。
标签:java,函数,学习,系统,语言,平台,方法,安装,QML,c++,数据 来源:
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。