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

网站建设标准规范济南谷歌推广

网站建设标准规范,济南谷歌推广,网页设计模板html代码和成果图,北京网站建设方案排名一、回顾一下jdk自带的类加载器: 1.java虚拟机自带的加载器 根类加载器(Bootstrap,c实现) 扩展类加载器(Extension,java实现) 应用类加载器(App,java实现) 2.用户自定义…

一、回顾一下jdk自带的类加载器:

1.java虚拟机自带的加载器 
    根类加载器(Bootstrap,c++实现) 
    扩展类加载器(Extension,java实现) 
    应用类加载器(App,java实现) 
2.用户自定义的类加载器 
    java.lang.ClassLoader的子类 
    用户可以定制类的加载方式

java的类加载机制默认情况下是采用委托模型:当加载某个类时JVM会首先尝试用当前类加载器的父类加载器加载该类,若父类加载器加载不到再由当前类加载器来加载,因此这种模型又叫做“父优先”模型
但是在实际项目中我们可能会要求先从当前类加载加载再从父类加载器加载,如项目中的某类的版本可能和container中的不一致的时候,若还从container加载就会报jar包冲突的异常,实际上jar包冲突的问题在实际开发过程中是经常会遇到的。
解决方案是通过扩展自定义的ClassLoader,重写loadClass方法,先从当前类加载器加载再从父类加载器加载。

二、用户自定义的类加载器:

要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用。

    protected Class findClass(String s)throws ClassNotFoundException{throw new ClassNotFoundException(s);}

示例:创建3个自定义类加载器,分别对应的父加载器如下图:

自定义类加载器:

package com.dxz.classloader;import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;public class MyClassLoader extends ClassLoader {// 类加载器名称private String name;// 加载类的路径private String path = "E:/";private final String fileType = ".class";public MyClassLoader(String name) {// 让系统类加载器成为该类加载器的父加载器super();this.name = name;}public MyClassLoader(ClassLoader parent, String name) {// 显示指定该类加载器的父加载器super(parent);this.name = name;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}@Overridepublic String toString() {return this.name;}/*** 获取.class文件的字节数组* * @param name* @return*/private byte[] loaderClassData(String className) {InputStream is = null;byte[] data = null;ByteArrayOutputStream baos = new ByteArrayOutputStream();className = className.replace(".", "/");try {is = new FileInputStream(new File(path + className + fileType));int c = 0;while (-1 != (c = is.read())) {baos.write(c);}data = baos.toByteArray();} catch (Exception e) {e.printStackTrace();} finally {try {is.close();baos.close();} catch (IOException e) {e.printStackTrace();}}return data;}/*** 获取Class对象*/@Overridepublic Class<?> findClass(String name) {byte[] data = loaderClassData(name);return this.defineClass(name, data, 0, data.length);}public static void main(String[] args)throws ClassNotFoundException, InstantiationException, IllegalAccessException {// loader1的父加载器为系统类加载器MyClassLoader loader1 = new MyClassLoader("loader1");loader1.setPath("E:/duan/lib1/");// loader2的父加载器为loader1MyClassLoader loader2 = new MyClassLoader(loader1, "loader2");loader2.setPath("E:/duan/lib2/");// loader3的父加载器为根类加载器MyClassLoader loader3 = new MyClassLoader(null, "loader3");loader3.setPath("E:/duan/lib3/");Class clazz = loader2.loadClass("com.dxz.classloader.Sample");Object object = clazz.newInstance();//object.main(null);
    }
}

 

package com.dxz.classloader;public class Hello {public Hello() {System.out.println("hello");}
}

被加载类-情况1:

package com.dxz.classloader;public class Sample {private String name = "hello world";public Sample() {System.out.println("one");new Hello();}public static void main(String[] args) {System.out.println(new Sample().name);}
}

并将生成的Sample.class文件拷贝到指定的目录下:

被加载类-情况2:

package com.dxz.classloader;public class Sample {private String name = "hello world";public Sample() {System.out.println("two");new Hello();}public static void main(String[] args) {System.out.println(new Sample().name);}
}

将新生成的Sample.class文件拷贝lib2下

被加载类-情况3:

package com.dxz.classloader;public class Sample {private String name = "hello world";public Sample() {System.out.println("three");new Hello();}public static void main(String[] args) {System.out.println(new Sample().name);}
}

将新生成的Sample.class文件拷贝lib3下

测试场景1:

        // loader1的父加载器为系统类加载器MyClassLoader loader1 = null;//new MyClassLoader("loader1");//loader1.setPath("E:/duan/lib1/");// loader2的父加载器为loader1MyClassLoader loader2 = new MyClassLoader(loader1, "loader2");loader2.setPath("E:/duan/lib2/");

 如果loader2的父加载器为空,则loader2加载器会去加载E:/duan/lib2/下的Sample.class文件,结果如下:

测试场景2:

       // loader1的父加载器为系统类加载器MyClassLoader loader1 = new MyClassLoader("loader1");loader1.setPath("E:/duan/lib1/");// loader2的父加载器为loader1MyClassLoader loader2 = new MyClassLoader(loader1, "loader2");loader2.setPath("E:/duan/lib2/");

结果:

结果说明:

当执行loader2.loaderClass("com.dxz.classloader.Sample")时,先由它上层的所有父加载器尝试加载Sample类。如果父加载loader1不为空,则loader1从D:/lib1/目录下成功的加载了Sample类,因此laoder1是Sample类的定义类加载器,loader1和loader2是Sample类的初始类加载器。

当执行loader3.loadClass("com.dxz.classloader.Sample")时,先由它上层的所有父加载器尝试加载Sample类。loader3的父加载器为根类加载器,它无法加载Sample类,接着loader3从D:/lib3/目录下成功地加载了Sample类,因此loader3是Sample类的定义类加载器即初始类加载器。

在Sample类中主动new Hello类,当执行Sample类的构造方法中的new Hello()语句时,Java虚拟机需要先加载Hello类,Java虚拟机会按Sample类的定义类加载器去加载Hello类,加载过程也同样采用父亲委托机制。

三、总结

自定义类加载器的核心在于对字节码文件的获取,如果是加密的字节码则需要在该类中对文件进行解密。由于这里只是演示,我并未对class文件进行加密,因此没有解密的过程。这里有几点需要注意:

  1、这里传递的文件名需要是类的全限定性名称,即com.paddx.test.classloading.Test格式的,因为 defineClass 方法是按这种格式进行处理的。

  2、最好不要重写loadClass方法,因为这样容易破坏双亲委托模式

  3、这类 Test 类本身可以被 AppClassLoader 类加载,因此我们不能把 com/paddx/test/classloading/Test.class 放在类路径下。否则,由于双亲委托机制的存在,会直接导致该类由 AppClassLoader 加载,而不会通过我们自定义类加载器来加载。

 

  双亲委派机制能很好地解决类加载的统一性问题。对一个 Class 对象来说,如果类加载器不同,即便是同一个字节码文件,生成的 Class 对象也是不等的。也就是说,类加载器相当于 Class 对象的一个命名空间。双亲委派机制则保证了基类都由相同的类加载器加载,这样就避免了同一个字节码文件被多次加载生成不同的 Class 对象的问题。但双亲委派机制仅仅是Java 规范所推荐的一种实现方式,它并不是强制性的要求。近年来,很多热部署的技术都已不遵循这一规则,如 OSGi 技术就采用了一种网状的结构,而非双亲委派机制。

http://www.lbrq.cn/news/2421703.html

相关文章:

  • 杭州企业网站优化哪家公司建设网站好
  • 衡水做网站开发的百度怎么发自己的小广告
  • 网站后台密码忘了怎么办今日头条新闻大事件
  • 上海网站建设lv cn在线bt磁力搜索
  • 做购物网站哪种服务器好整合营销经典案例
  • 做任务兼职赚钱的网站有哪些链网
  • 电商网站开发文献汇总seo优化查询
  • 西安网站建站优化网站推广软件免费
  • 建站吧网站建设seo优化平台
  • 宝安最好的网站建设在线视频用什么网址
  • 网站做推广需要营业执照广东seo网站推广代运营
  • 建立网站的优势crm
  • 新鸿儒网站seo教程论坛
  • 社区做图网站北京网站推广排名服务
  • 上海电子通科技网站建设seoul怎么读
  • 兖州网站建设有没有自动排名的软件
  • 网站建设的产品类型是什么电脑培训网
  • 手把手做网站页面网站关键词怎么设置
  • 用别人的资源做网站营销策划品牌策划
  • 西宁做网站君博专注中国局势最新消息今天
  • 网站的设计分析ks数据分析神器
  • 云南建投第五建设有限公司网站百度指数数据官网
  • 南京网站开发公司哪家好电子商务营销的概念
  • 浏览器下载免费版百度地图排名可以优化吗
  • 百度推广电话号码seo营销专员
  • 定制小程序开发公司百度seo软件首选帝搜软件
  • 阿里巴巴建设网站泉州百度seo
  • 增城网站建设方案360开户
  • 哪里做网站一套一百平台运营推广方案
  • 软件开发网站建设seo网站优化培训怎么样
  • Fluent许可与网络安全策略
  • Linux中ELF区域与文件偏移量的关系
  • 解决win10下Vmware虚拟机在笔记本睡眠唤醒后ssh连接不上的问题
  • 探索无广告音乐世界:MusicFree 免费播放器
  • MySQL笔记3
  • 30天打牢数模基础-K均值聚类