自定义了类加载器为啥只能通过反射创建对象,想new就没有办法了吗
1条回答 默认 最新
- blackoon88 2022-05-14 17:17关注
指定外部的class文件,只能通过反射创建对象;在破坏双亲委派原则的情况下,虽使用自定义的类加载器,但是你要使用类加载load然后创建对象。所以要使用自定义的类加载器就不能通过new的方式创建对象。
参照代码如下:
package com.demo1; import java.io.IOException; import java.io.InputStream; /** * @Author blackoon88 * @Date 2022/5/14 */ public class MyClassLoader2 extends ClassLoader{ public static void main(String[] args) throws Exception { /** * 重写loadClass,违背了双亲委派原则。 * 因为双亲委派的逻辑是在loadClass中通过递归实现 * 正确操作为重写findClass */ ClassLoader load = new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { try { String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; InputStream resourceAsStream = getClass().getResourceAsStream(fileName); if (resourceAsStream == null) { return super.loadClass(name); } byte[] b = new byte[resourceAsStream.available()]; resourceAsStream.read(b); return defineClass(name, b, 0, b.length); } catch (IOException e) { throw new ClassNotFoundException(); } } }; ClassLoader find = new ClassLoader() { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; InputStream resourceAsStream = getClass().getResourceAsStream(fileName); if (resourceAsStream == null) { return super.findClass(name); } else { byte[] b = new byte[0]; try { b = new byte[resourceAsStream.available()]; resourceAsStream.read(b); } catch (IOException e) { e.printStackTrace(); } return defineClass(name, b, 0, b.length); } } }; // 重写loadClass,破坏双亲委派原则,但会使用自定义的类加载器 Object loadObject = load.loadClass("com.demo1.MyClassLoader2").newInstance(); System.out.println("load:"+ loadObject.getClass().getClassLoader()); System.out.println(loadObject instanceof MyClassLoader2); System.out.println("------------------------------------------------------"); // 重写findClass,运行时由于要加载的类在classpath下已经编译好,则会用AppClassLoader来加载, // 如果要使用自定义累加器的加载,则应该使用类路径classpath外的一个class文件,并且类路径下不能包含此class // 才能使用到自定义的类加载器 Object findObject = find.loadClass("com.demo1.MyClassLoader2").newInstance(); System.out.println("find:"+ findObject.getClass().getClassLoader()); System.out.println(findObject instanceof MyClassLoader2); } }
若有帮助,谢谢采纳~
解决 1无用