java new对象的类加载器是谁?
Posted master-dragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java new对象的类加载器是谁?相关的知识,希望对你有一定的参考价值。
关于java new 对象使用的流程我们都知道如下图所示:
注:图片来自网络
但是究竟是谁(即哪个类加载器)完成【加载】的呢?
如下两个类:
- Test
package com.hotload;
/**
* @Author mubi
* @Date 2020/7/27 08:49
*/
public class Test {
public Test() {
}
public String hello(String msg){
return "hello:" + msg;
}
public Test2 getTest2(){
return new Test2();
}
}
- Test2
package com.hotload;
/**
* @Author mubi
* @Date 2020/7/27 08:49
*/
public class Test2 {
public Test2() {
}
public String hello2(){
return "test2";
}
}
普通java程序下,都是sun.misc.Launcher$AppClassLoader
加载的
当使用自定义类加载器获取Test2对象就发现不同了
即不同的地方new同样的对象(Test2在不同的地方new的),结果是不同的;都是new,但是使用的类加载器是不同的
附code:
public static void main(String[] args) throws Exception {
String rootPath = "/Users/mubi/git_workspace/java8/java8-api/src/main/java";
MyComOtherClassLoader myClassLoader = new MyComOtherClassLoader();
myClassLoader.path = rootPath;
Class clz = Class.forName("com.hotload.Test", true, myClassLoader);
Object test = clz.newInstance();
System.out.println(test.getClass().getClassLoader());
Method method = clz.getMethod("getTest2");
Object test2 = method.invoke(test);
System.out.println(test2.getClass().getClassLoader());
}
package com.hotload;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @Author mubi
* @Date 2019/3/20 10:54 PM
*/
public class MyComOtherClassLoader extends ClassLoader {
public String path;
public String packageName;
public String className;
public MyComOtherClassLoader() {
super(ClassLoader.getSystemClassLoader());
}
private String classNameToPath() {
// 得到类文件的URL
return path + "/" + packageName.replace('.', '/')
+ "/"
+ className + ".class";
}
@Override
public Class loadClass(String name) throws ClassNotFoundException {
// 非 com.hotload package下面的类,都用默认的加载,否则用自定义的加载方法
if (!name.contains("com.hotload")) {
// 是否已经被加载
Class loadedClass = findLoadedClass(name);
if (loadedClass == null) {
// 用父类去加载该类
loadedClass = getParent().loadClass(name);
return loadedClass;
} else {
return loadedClass;
}
}
int i = name.lastIndexOf('.');
packageName = "";
if (i != -1) {
packageName = name.substring(0, i);
// System.out.println("package: " + packageName);
className = name.substring(i + 1);
// System.out.println("class name: " + name);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(packageName);
}
}
//依然调用父类的方法
// return super.loadClass(name);
return this.findClass(name);
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
int i = name.lastIndexOf('.');
packageName = "";
if (i != -1) {
packageName = name.substring(0, i);
// System.out.println("package: " + packageName);
className = name.substring(i + 1);
// System.out.println("class name: " + name);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPackageAccess(packageName);
}
}
Class<?> clazz = this.findLoadedClass(name); // 父类已加载
if(null != clazz){
return clazz;
}
// System.out.println("findClass param name: " + name);
byte [] b = this.getClassBytes();
// System.out.println("b len:" + b.length);
clazz=defineClass(null, b, 0, b.length);
return clazz;
}
public byte[] getClassBytes() {
String classPath = classNameToPath();
// System.out.println("classPath:" + classPath);
File file=new File(classPath);
try(FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream bos=new ByteArrayOutputStream();) {
byte[] b=new byte[1024*2];
int n;
while((n=fis.read(b))!=-1){
bos.write(b, 0, n);
}
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
以上是关于java new对象的类加载器是谁?的主要内容,如果未能解决你的问题,请参考以下文章