当前位置: 首页 > news >正文

我的家乡网页设计素材西安网络seo公司

我的家乡网页设计素材,西安网络seo公司,如何搭建自己的小程序,南阳网站建设哪家好一、What(是什么?)1、概念Java类加载器是Java运行时环境的一部分,负责动态加载Java类到JVM的内存空间中。每个Java类必须由某个类加载器装入到内存中。每一个类加载器都有一个父类加载器(BootStrap引导类加载器没有)。2、 JVM中有…

一、What(是什么?)

1、概念

Java类加载器是Java运行时环境的一部分,负责动态加载Java类到JVM的内存空间中。每个Java类必须由某个类加载器装入到内存中。每一个类加载器都有一个父类加载器(BootStrap引导类加载器没有)。

2、 JVM中有3个默认的加载器:

(1) BootStrap:引导类加载器。这个加载器很特殊,它不是JAVA类,因此它不需要被别人加载,它嵌套在JVM内核里,也就是说JVM启动的时候BootStrap就启动了,它是C++写的二进制代码,可以加载别的类。这也是为什么System.class.getClassLoader()结果为null的原因,因为它不是JAVA类,所以它的引用返回null。负责加载核心Java库,存储在<JAVA_HOME>/jre/lib/rt.jar

(2) ExtClassLoader:扩展类加载器。

(3) AppClassLoader:根据类路径来加载java类。一般我们自定义的类都是通过这个AppClassLoader加载。

3、类加载器及其委托机制

6f6a34c2946811422eb1d5bf00119e5f.png

(1) 当Java虚拟机加载一个类时,如何加载呢?

首先当前线程的类加载器去加载线程中的第一个类(如类A):

l 如果类A引用了类B,Java虚拟机将加载类A的加载器去加载类B

l 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类

(2) 委托机制的作用—防止内存中出现多分同样的字节码

例如类A和类B都要加载System类:

l 如果不用委托机制,都是自己加载,那么类A会加载一份Sysem字节码,同时类B也会加载一份字节码看,这样内存中就出现了两份System字节码。

l 如果使用委托机制,会递归地向父类查找,首选用BootStrap尝试加载,如果找不到就向下。这里System就能在BootStrap中找到然后加载。如果此时B也加载System,也从BootStrap,此时BootStrap发现已经加载过System字节码,则直接返回内存中的System字节码而不是重新加载,这样就保证了内存中只有一份字节码。

例如:用户使用一个自定义的类(没有使用自定义类加载器),那么系统就开始从AppClassLoader向父类加载器发送请求,一直到BootStrap,然后BootStrap类加载器没有父类,于是就开始查找对应路径下是否有符合要求的类。如果没有,则又向下查询,最终回到AppClassLoader(请求的发起者),如果有则返回,没有则会抛出ClassNotFoundException的异常。如果在AppClassLoader之前,其他类加载器已经找到,则由对应的类加载其返回。

代码实例1:

public class ClassLoaderTest {public static void main(String[] args)   {System.out.println(ClassLoaderTest.class.getClassLoader().getClass().getName());System.out.println("=========================================");ClassLoader loader = ClassLoaderTest.class.getClassLoader();while(loader != null) {System.out.println(loader.getClass().getName());loader = loader.getParent();}System.out.println(loader);}
}

5ea97f7b792aef7114df3b514cc0af08.png

代码实例2:

首先我们自定义一个类:

public class Secret{public String key(){return "The key is 5132561";}}

然后打印加载这个类的类加载器:

System.out.println(new Secret().getClass().getClassLoader().getClass().getName());

输出结果如下:

29808623149787ab102e5a7a0567128e.png

因为从BootStrapèExtClassLoaderèAppClassLoader这个过程中,只有到AppClassLoader才找到对应的类,所以打印AppClassLoader。

代码实例3:

如果我们将Secret的字节码打成jar包并放到ExtClassLoader所指向的目录–<JAVA_HOME>/jre/lib/ext目录下,那么BootStrapèExtClassLoader,到ExtClassLoader就找到了对应的类并返回,这时就打印ExtClassLoader。

打包成jar包并保存到<JAVA_HOME>/jre/lib/ext目录下。

90ff8e53335c0044502b5e2305788c44.png

a111272fdf9809adddf5f262250bf738.png

再次输出:

System.out.println(new Secret().getClass().getClassLoader().getClass().getName());

6d3d61dbfb99f24982effbe188094150.png

二、How(如何自定义类加载器?)

自定义的类加载器必须继承ClassLoader,并实现重载findClass方法。

代码实例:

public class DecodeClassLoader extends ClassLoader{private String classDir;public DecodeClassLoader(){}public DecodeClassLoader(String classDir){this.classDir = classDir;}@Overrideprotected Class<?> findClass(String name) {File f = new File(classDir,name.substring(name.lastIndexOf(".") + 1) + ".class");try {InputStream in = new FileInputStream(f);ByteArrayOutputStream out = new ByteArrayOutputStream();encode(in, out);byte[] bytes = out.toByteArray();in.close();out.close();return defineClass(bytes, 0, bytes.length);} catch (FileNotFoundException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}return  null;}private static void encode(InputStream in, OutputStream out) throws IOException{int b = 0;while((b=in.read())!= -1){out.write(b ^ 0xff);}}	
}

三、Where(在什么地方使用?)

(1)运行时装载或卸载类。常用于:

  • 实现脚本语言
  • 用于bean生成器
  • 允许用户定义的扩展性
  • 允许命名控件之间的通信。

(2)改变Java字节码的装入,例如Java类字节码的加密

(3)修改以装入的字节码

四、类加载器的综合应用实例

通过一个加密类对一个重要的类字节码进行加密,使得只有使用解密类加载器才可以成功加载并使用。示意图如下:

7b7bed1446863532cf25c4535e9786f4.png

0c3995e2edae0d5bfa98ba6c6d1c8216.png

(1)DecodeClassLoader.java见上面。

(2)加密类:对Secret字节码进行加密

public class EncodeUtil {private static void encode(InputStream in, OutputStream out) throws IOException{int b = 0;while((b=in.read())!= -1){out.write(b ^ 0xff);}}public static void main(String[] args) throws IOException {String srcPath = "E:java_workspace004ClassLoaderDemobincomshuwoomclassloaderSecret.class";//args[0];String destDir = "shuwoomlib";FileInputStream in = new FileInputStream(srcPath);String destFileName = srcPath.substring(srcPath.lastIndexOf("") + 1);String destPath = destDir + "" + destFileName;System.out.println(destPath);FileOutputStream out = new FileOutputStream(destPath);encode(in,out);in.close();out.close();}
}

(3)被加载的类:

public class Secret{public String key(){return "The key is 5132561";}
}

首先运行EncodeUtil加密工具类,将Secret.class文件加密并保存到指定的shuwoomlib目录下,此时,在bin/bom/shuwoom/classloader目录下的Secret是未经加密的字节码。现在我们将shuwoomlib目录下加密的Secret.class替换掉bin/bom/shuwoom/classloader目录下的Secret.class。那么AppClassLoader找到的就是经过加密的字节码。

416b823ff5901dc565b1ecf9f6920aa1.png

e44eda83decd6f16763d49cb1f1e0fad.png

//如果直接使用AppClassLoader加载,会报错。

System.out.println(new Secret().key());

编译运行会报错:

273d76fd014d39ebb298f49f38fb773f.png

//通过DecodeClassLoader类加载器获得Secret原字节码

ClassLoader classLoader = new DecodeClassLoader("shuwoomlib");
Class clazz = classLoader.loadClass("Secret");Method getKeyMethod = clazz.getMethod("key");
System.out.println(getKeyMethod.invoke(clazz.newInstance(), null));

此时才能正常使用。

dadf37ac8526c2900407f66e02bc3f76.png
http://www.lbrq.cn/news/2625553.html

相关文章:

  • 做网站在哪里可以找到高清壁纸seo推广多少钱
  • 游戏类网站怎么做免费推广网
  • 杭州维利国德网站建设案例网络营销的主要内容有哪些
  • java程序员做自己的网站手机怎么制作网页
  • 上海金山网站建设公司网络营销的含义
  • 广德做网站网站的优化公司
  • 网站建设 环保素材青岛关键词排名提升
  • 网站创建方案论文百度站长工具怎么用
  • 专题网站建设的请示友情链接交换平台源码
  • 如何做网站的内链优化抖音seo关键词优化排名
  • 政府门户网站建设策略研究关键词搜索趋势
  • 建站之星成品网站源码关键词优化公司哪家好
  • 乐清开发网站公司成都百度seo公司
  • 清远建设工程招投标网站seo 优化思路
  • 湘潭整站优化网络广告营销案例分析
  • 盗版网站是如何做的网站多少钱
  • 广州做购物网站靠谱的seo收费
  • 常州网站建设大全微信营销推广软件
  • 网站建设的基本特点seo优化诊断
  • 摄影素材网站餐饮最有效的营销方案
  • seo网站结构图网络推广员怎么做
  • 模仿 网站关键词seo排名怎么选
  • 网站前端培训深圳seo优化公司
  • 做网站还需要搜狗吗seo优化就业前景
  • 网站可以做视频链接江门seo外包公司
  • 网页视频怎么下载下来高手优化网站
  • 做网站业务员如何跟客户沟通营销最好的方法
  • wordpress赞赏功能杭州seo百度关键词排名推广
  • 怎么用java做动态网站10000个免费货源网站
  • 东莞网站建设vipbaikeseo的优点
  • TrustZone技术详解————这篇是AI写的包括图
  • 第14届蓝桥杯Scratch_选拔赛_初级及中级(STEMA)真题2022年12月18日
  • 【VS + Qt】VS2022 Qt 开发中 ui_xx.h 文件编辑报错但编译正常的问题解决
  • 【数据结构与算法】刷题篇——环形链表的约瑟夫问题
  • Javascript/ES6+/Typescript重点内容篇——手撕(待总结)
  • Redis之Set和SortedSet类型常用命令