您的位置:首页技术文章
文章详情页

java - 匿名内部类和继承类,在实现ClassLoader时为什么会有区别

【字号: 日期:2023-11-29 09:52:36浏览:49作者:猪猪

问题描述

最近在看Java虚拟机,类加载器那节举了这么一个例子:

/***类加载器与instanceof关键字演示**@author zzm*/public class ClassLoaderTest{ public static void main(String[]args) throws Exception{ClassLoader myLoader=new ClassLoader(){ @Override public Class<?>loadClass(String name)throws ClassNotFoundException{try{ String fileName=name.substring(name.lastIndexOf('.')+1)+'.class'; InputStream is=getClass().getResourceAsStream(fileName); if(is==null){return super.loadClass(name); } byte[]b=new byte[is.available()]; is.read(b); return defineClass(name,b,0,b.length);}catch(IOException e){ throw new ClassNotFoundException(name);} }};Object obj=myLoader.loadClass('org.fenixsoft.classloading.ClassLoaderTest').newInstance();System.out.println(obj.getClass());System.out.println(obj instanceof org.fenixsoft.classloading.ClassLoaderTest);//false }}

总而言之就是用自定义的类加载器去加载一个类,返回的类与jvm自带的SystemClassLoader加载的类不同。

那么如果用一个继承自ClasserLoader的类,按理说也是同样的效果

package jvm;public class MyClassLoader extends ClassLoader{ @Override public Class<?> loadClass(String fullClassName) throws ClassNotFoundException{try { String fileName = fullClassName.substring(fullClassName.lastIndexOf('.')+1,fullClassName.length())+'.class'; InputStream is = getResourceAsStream(fileName); if(is==null){return super.loadClass(fullClassName); } byte[] bytes = new byte[is.available()]; is.read(bytes); return defineClass(fullClassName,bytes,0,bytes.length);}catch (Exception e){ throw new ClassNotFoundException();} } public static void main(String[] args) throws Exception{ClassLoader myClassLoader = new MyClassLoader();/**ClassLoader myClassLoader = new ClassLoader() { @Override public Class<?> loadClass(String fullClassName) throws ClassNotFoundException {try { String fileName = fullClassName.substring(fullClassName.lastIndexOf('.')+1,fullClassName.length())+'.class'; InputStream is = getClass().getResourceAsStream(fileName); if(is==null){return super.loadClass(fullClassName); } byte[] bytes = new byte[is.available()]; is.read(bytes); return defineClass(fullClassName,bytes,0,bytes.length);}catch (Exception e){ throw new ClassNotFoundException();} }};/**/ClassLoader systemClassLoader = java.lang.ClassLoader.getSystemClassLoader();Class myClass = myClassLoader.loadClass('jvm.MyClassLoader');Class systemClass = systemClassLoader.loadClass('jvm.MyClassLoader');Object myObj = myClass.newInstance();Object systemObj = systemClass.newInstance();System.out.println(myClass.equals(systemClass));//trueSystem.out.println(myObj.getClass().equals(systemObj.getClass()));//true }}

注释里的代码就是匿名内部类的继承,注意到这里myClass和systemClass是完全相等的,但是myClass是使用继承自ClassLoader的类MyClassLoader生成的,请问这是为什么呢。。。

问题解答

回答1:

第二个代码走到

if(is==null){ return super.loadClass(fullClassName);}

加载class文件用getClass().getResourceAsStream

标签: java