扫码关注公众号

JVM虚拟机之类的加载过程
05-22
147观看
01

如何使一个类不可变?

1.将类声明为final,使其无法被继承。2.所有域都用private修饰,不允许直接访问。3.不提供变量的setter方法。4.所有可变域

来自:jvm虚拟机相关-类的加载过程
02

以下哪项不属于java类加载过程?

正确答案是B类从被加载到虚拟机内存中开始,到卸载出内存开始,他的整个生命周期包括:1、加载(Loading,2、验证(Verification),3、准备(Prepation),4、解析(Resolution),5、初始化(Initialization),6、使用(Using)7、卸载(Unloading)7个阶段。其中准备、验证、解析3个部分统称为连接(Linking)

来自:jvm虚拟机相关-类的加载过程
03

类加载的方式(百度面试题)

类加载分为动态加载和静态加载。动态加载是从外存储器中加载类,一般类加载机制分析的也是动态加载。静态加载本质上是从内存中创建类的实例对象,此时类已经被加载到内存中。一.静态加载1.通过new关键字来创建Test的实例对象。二.动态加载1.通过Class.forName()来加载类,然后调用类的newInstance()方法实例化对象。2.通过类加载器的loadClass()方法来加载类,然后调用类的newInstance()方法实例化对象。这里有几个需要比较的地方:1.通过new关键字实例化类的对象和通过Class.forName()加载类是当前类加载器。即this.getClass.getClassLoader,只能在当前类路径或者导入的类路径下寻找类。而用指定的classLoader来加载类可以从当前路径外寻找类,这里的classLoader甚至可以用户自定义。2.我们知道类加载机制的三个过程主要是加载-->连接-->初始化。Class.forName()实际调用的是Class.forName(className,true,this.getClass.getClassLoader),第二个参数表示加载完后是否立即初始化,第三个参数即前文提到的表示是当前类加载器。classLoader.loadClass()实际调用的是classLoader.loadClass(className,false),第二个参数表示加载完成后是否连接,即用此方法加载类,加载完成后不会去初始化,而用Class.forName()加载类加载完成后可以被初始化。所以有些类如果加载完成后需要立即被初始化则必须使用Class.forName()。例如在加载数据库驱动时,一般用Class.forName("com.mysql.jdbc.Driver")。这是因为该驱动有一个在静态代码块中注册驱动的过程,所以需要被初始化。3.有两个异常静态加载类时出现的一般是NoClassDefFoundError。动态加载类时出现的一般是ClassNotFoundException。这两者经常被用来比较,其实区别很大。NoClassDefFoundError是错误,不方便被捕捉也不需要被捕捉,不应该尝试从error中恢复程序。他是由于在使用new关键字实例化类的对象时,在内存中找不到对象了,一般比较少见,在运行时发生,即编译时可以找到类运行时却找不到了。而ClassNotFoundException是异常,是可以被捕捉的,应该捕捉并处理尝试恢复程序。这是由于利用类名动态加载类的时候,在外存储器类路径下找不到该类或者其依赖的jar包,还有一个导致其的原因是在同一个包中同一个类被不同的类加载器加载了两遍。

来自:jvm虚拟机相关-类的加载过程
04

在 Java 中,为什么不允许从静态方法中访问非静态变量?

1.静态变量属于类本身,在类加载的时候就会分配内存,可以通过类名直接访问;2.非静态变量属于类的对象,只有在类的对象产生时,才会分配内存,通过类的实例去访问;3.静态方法也属于类本身,但是此时没有类的实例,内存中没有非静态变量,所以无法调用。

来自:jvm虚拟机相关-类的加载过程
课程
专栏
java语言-jvm虚拟机相关-类的加载过程
3专栏
1课程
4 试题