① java中的“类”是什么时候被加载到虚拟机
1、编译和运行概念要搞清:编译即javac的过程,负责将.java文件compile成.class文件,主要是类型、格式检查与编译成字节码文件,而加载是指java *的过程,将.class文件加载到内存中去解释执行,即运行的时候才会有加载一说。
2、类的加载时机,肯定是在运行时,但并不是一次性全部加载,而是按需动态,依靠反射来实现动态加载,一般来说一个class只会被加载一次,之后就会从jvm的class实例的缓存中获取,谁用谁取就可以了,不会再去文件系统中加载.class文件了。
② java虚拟机什么情况下会对java类进行加载
王森的《Java深度历险》详细说了这个问题。大致是jvm先加载Object类,再加载该类的超类,再加载该类本身,当该类被指向null时,该类被垃圾回收机制处理,当垃圾回收机制执行时会被清楚。
静态代码块会在类被创建或被调用的时候就被初始化,被创建和被调用是不同的两个概念,比如User u = new User();这个时候u没有被调用,不过静态模块已经被加载执行,而User.class;这条语句User并没有创建出实例,不过却被调用了,这个时候静态的代码块也被加载。不过,静态代码块有一个很特别的地方就是,在同一个应用程序中,只会执行一次。下面是一个Demo,可以看看:
public class User{
static {
System.out.println("It's a static space");
}
public static String name = "Jim Green";
}
另一个类调用,直接写main方法了。
public static void main(String[] args){
User u = new User();
String name = User.name;
}
这里会输出一句It's a static space,而注释掉其中任何一句依然会输出。不过,如果这个main方法卸载User里时,main方法什么都不写都会输出It's a static space,楼主可以想想是为什么。
③ Java虚拟机是如何加载Java类的
加载:双亲委派模型,每当一个类的加载器接收到加载请求时,它会先将请求转发给父加载器。
JAVA9之前,启动类加载器负责加载最为基础最为重要的类,比如lib目录下。除了启动加载器,另外两个重要的类加载器
扩展类加载器(lib/ext下的),应用加载器(应用程序路径下的类)。
④ Java虚拟机加载class
可以,前提是包名不同。
⑤ java什么时候使用显式类加载
隐式加载是通过new等途径生成的对象时jvm把相应的类加载到内存中
显示加载是通过Class.forName(..)等方式由程序员自己控制加载
new是硬编码,然而在大部分情况下,new这种硬编码够用了。
Class.forName(String)可以动态加载,这增强了java的动态性。也就是说你可以在运行时选择加载A类或者B类。
if (condition_a) {
Class cls = Class.forName("A");
else if (condition_b) {
Class cls = Class.forName("B");
} else {
Class cls = Class.forName("Other");
}
⑥ 只要正常编译类文件类就会加载吗java类到底是什么时候加载的
除了先把保证程序运行的基础类一次性加载到jvm别的都是用到了才会加载.好像是这样,前几天看的,也没专心记
⑦ class 类 什么 时候被 加载 java虚拟机内存
编写的java文件经过编译之后形成字节码文件,当你的程序在运行中调用到该class类的时候,通过ClassLoader进行加载。下面详细介绍下。
class文件从加载到jvm内存中开始,到卸载出内存为止,他的整个生命周期(整个加载过程)包括:加载,验证,准备,解析,初始化,使用和卸载。其中验证,准备,解析三个合称为连接。下面重点说一下加载过程。
加载过程:
1、通过一个类的全限定名来获取定义此类的二进制字节流
2、将字节流所代表的静态存储结构转化为方法区的运行时存储结构
3、在java堆中生成一个代表该类的对象,作为方法区这些数据的访问入口
验证:
1、文件格式验证:是否以魔数0xCAFEBABE开头,class文件的主次版本号是否在当前jvm处理范围之内,常量池的常量中是否有不被支持的类型,指向常量中的索引值有无不存在的常量,等
2、元数据验证:对字节码描述的信息进行语义分析,保证符合java规范。如是否有父类,是否继承了不允许继承的类,如果不是抽象类,是否实现了所有未实现的方法。等
3、字节码验证:数据流和控制流分析。主要针对类的方法体。
4、符号引用验证:如符号引用中通过字符串描述的全限定名是否能够找到对应的类等
准备:
该阶段正式为类变量分配内存并设置初始值。内存在方法区中分配。这里说的初始值是通常情况下说的零值。
解析:
虚拟机将常量池中的符号引用替换为直接引用的过程。包括:
1、类或接口的解析
2、字段解析
3、类方法解析
4、接口方法解析
初始化:
类初始化阶段是类加载过程的最后一步,除了加载阶段用户可以通过自定义加载器参与外,其余动作完全由虚拟机指导控制。到了初始化阶段,才真正开始执行类中定义的java程序代码(字节码)。在准备阶段,变量已经赋过一次系统默认值,而在初始化阶段,则是根据程序制定的主观计划去初始化类变量和其他资源,即初始化阶段是执行类构造器<clinit>()方法的过程。<clinit>是在编译java源码时,按照静态块和静态变量赋值语句的顺序生成的。如果类没有静态块也没有为静态变量赋值,就不会生成<clinit>方法,该方法只能被虚拟机调用。
⑧ 描述java虚拟机加载类的过程,要详尽!
先将class文件读到JVM,找到static
的变量并初始化,在找到static代码段执行,在初始化普通变量,然后是构造方法。最后载入其他方法。
⑨ Java中的类是什么时候被加载到虚拟机
这个问题java的比较核心的一个难题,我就针对问题做简要回答,不做深入讨论了:
1、编译和运行概念要搞清:编译即javac的过程,负责将.java文件compile成.class文件,主要是类型、格式检查与编译成字节码文件,而加载是指java *的过程,将.class文件加载到内存中去解释执行,即运行的时候才会有加载一说。
2、类的加载时机,肯定是在运行时,但并不是一次性全部加载,而是按需动态,依靠反射来实现动态加载,一般来说一个class只会被加载一次,之后就会从jvm的class实例的缓存中获取,谁用谁取就可以了,不会再去文件系统中加载.class文件了。
明白1,2点就够了,再深入要等一段才能明白了。
⑩ java中什么时候类第一次加载
建议楼主在类中增加一段静态代码,然后跟踪一下,这样有助于您理解类的加载时间。
例如
public class Test
{
static{System.out.println("Load Test");}
...
}