Java编程:为什么Class实例可以不是全局唯一
通过定义两个类加载器加载同一字节码文件来证明Class实例为什么不是全局唯一的
1.将一个名为Demo(没有后缀)的字节码文件放在D盘根目录
2.定义两个类加载器
自定义ClassLoader三要素:
- 继承自ClassLoader,重写findClass()
 
- 获取字节码二进制流
 
- defineClass加载生成Class实例
 
package pkg.custom;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
/**
 * 自定义ClassLoader三要素:
 * 1. 继承自ClassLoader,重写findClass()
 * 2. 获取字节码二进制流
 * 3. defineClass加载生成Class实例
 */
public class MyClassLoader1 extends ClassLoader {
    private final String CLASS_PATH = "d://Demo";
    protected Class<?> findClass(String name) {
        try {
            //获取字节码二进制流
            FileInputStream in = new FileInputStream(this.CLASS_PATH);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = in.read(buf)) != -1) {
                baos.write(buf, 0, len);
            }
            in.close();
            byte[] classBytes = baos.toByteArray();
            //加载Class字节码
            return defineClass(classBytes, 0, classBytes.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
//===========================================================
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
public class MyClassLoader2 extends ClassLoader {
    private final String CLASS_PATH = "d://Demo" ;
    protected Class<?> findClass(String name) {
        try {
            FileInputStream in = new FileInputStream(this.CLASS_PATH) ;
            ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
            byte[] buf = new byte[1024] ;
            int len = -1 ;
            while((len = in.read(buf)) != -1){
                baos.write(buf , 0 , len);
            }
            in.close();
            byte[] classBytes = baos.toByteArray();
            return defineClass( classBytes , 0 , classBytes.length) ;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null ;
    }
}
3.Main函数
public class Application {
    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader c1 = new MyClassLoader1() ;
        //利用自定义加载器1加载对象
        //调用ClassLoader.loadClass()加载字节码会自动调用findClass方法
        Class<?> clz1 = c1.loadClass("Demo");
        System.out.println(clz1.getClassLoader() + "|hashcode:" + clz1.hashCode());
        ClassLoader c2 = new MyClassLoader2() ;
        //利用自定义加载器2加载对象
        Class<?> clz2 = c2.loadClass("Demo");
        System.out.println(clz2.getClassLoader() + "|hashcode:" + clz2.hashCode());
    }
}
运行main,得到输出结果:
pkg.custom.MyClassLoader1@74a14482|hashcode:1735600054
pkg.custom.MyClassLoader2@7f31245a|hashcode:325040804
可以看出由两个不同的类加载器加载,两者的哈希值不同,即所得到的类对象是不同的。
结论:
- 同一个Class被不同的类加载器加载后在JVM中产生的类对象是不同的
- 在同一个类加载器作用范围内Class实例加载时才会保持唯一性
Java编程:为什么Class实例可以不是全局唯一的更多相关文章
- 为什么Class实例可以不是全局唯一的——自定义类加载器
		为什么Class实例可以不是全局唯一的 通过定义两个类加载器加载同一字节码文件来证明Class实例为什么不是全局唯一的 1.将一个名为Demo(没有后缀)的字节码文件放在D盘根目录 2.定义两个类加载 ... 
- 《Java编程思想》学习笔记(二)——类加载及执行顺序
		<Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ... 
- #Java编程思想笔记(一)——static
		Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ... 
- Java编程思想重点笔记(Java开发必看)
		Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ... 
- JAVA编程讲座-吴老
		JAVA系列公开课第4讲:多态系列课程:从JAVA编程零基础讲起,同时结合工作中遇到的具体实例,语言清晰易懂,连续10周+深入讲解,打下编程基础,让我们一起打来自动化测试的大门时间:4月25日(周一) ... 
- Google Java编程风格指南
		出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ... 
- 谷歌Java编程规范
		Google Java编程风格指南 January 20, 2014 作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声 ... 
- Java编程中“为了性能”尽量要做到的一些地方
		最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ... 
- JAVA编程“性能说”(java编程需要做的26件事)
		转载于 http://www.csdn.net/article/2012-06-01/2806249 最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过 ... 
随机推荐
- 开源基于docker的任务调度器pipeline,比`quartzs` 更强大的分布式任务调度器
			pipeline 分布式任务调度器 目标: 基于docker的布式任务调度器, 比quartzs,xxl-job 更强大的分布式任务调度器. 可以将要执行的任务打包为docker镜像,或者选择已有镜像 ... 
- (数据科学学习手札125)在Python中操纵json数据的最佳方式
			本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在日常使用Python的过程中,我们经常会 ... 
- javascript获取焦点对象ID
			document.activeElement 方法:if(document.activeElement.id="textbox1") { } 
- #使用C#winform编写渗透测试工具--子域名挖掘
			使用C#winform编写渗透测试工具--子域名挖掘 这篇文章主要介绍使用C#winform编写渗透测试工具--子域名挖掘.在渗透测试中,子域名的收集十分重要,通常一个网站的主站的防御能力特别强,而他 ... 
- linux对拍
			转自 hzoi-fengwu :https://www.cnblogs.com/hzoi-fengwu/p/14872962.html 1 #include<bits/stdc++.h> ... 
- NCB | 定量蛋白质组学揭示细胞外泌体通用标志物Syntenin-1
			外泌体 (exosomes) 是由哺乳动物细胞通过"内吞-融合-外排"等机制,主动向胞外释放的纳米级 (直径40~60 nm) 双层囊泡小体,携带蛋白质.核酸.脂质等多种生物活性分 ... 
- UE4点选源码分析
			在UE插件开发中,时常会用到场景预览窗口的功能,也经常会有点选场景里的物体而同步改变工具界面的需求,网上教程多为讲解如何打开一个预览界面.在最近的一次需求开发中,我粗读了关卡编辑器和蓝图编辑器的Vie ... 
- Numpy数组的组合与分割详解
			在介绍数组的组合和分割前,我们需要先了解数组的维(ndim)和轴(axis)概念. 如果数组的元素是数组,即数组嵌套数组,我们就称其为多维数组.几层嵌套就称几维.比如形状为(a,b)的二维数组就可以看 ... 
- Git-06-远程仓库
			本地仓库推送到远程仓库 1 创建ssh key 用户主目录下运行如下命令,然后一路回车 ssh-keygen -t rsa -C "1029612787@qq.com" 2 找到公 ... 
- Java通过SSLEngine与NIO实现HTTPS访问
			Java使用NIO进行HTTPS协议访问的时候,离不开SSLContext和SSLEngine两个类.我们只需要在Connect操作.Connected操作.Read和Write操作中加入SSL相关的 ... 
