通过定义两个类加载器加载同一字节码文件来证明Class实例为什么不是全局唯一的

1.将一个名为Demo(没有后缀)的字节码文件放在D盘根目录

2.定义两个类加载器

自定义ClassLoader三要素:

    1. 继承自ClassLoader,重写findClass()
    1. 获取字节码二进制流
    1. 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实例可以不是全局唯一的更多相关文章

  1. 为什么Class实例可以不是全局唯一的——自定义类加载器

    为什么Class实例可以不是全局唯一的 通过定义两个类加载器加载同一字节码文件来证明Class实例为什么不是全局唯一的 1.将一个名为Demo(没有后缀)的字节码文件放在D盘根目录 2.定义两个类加载 ...

  2. 《Java编程思想》学习笔记(二)——类加载及执行顺序

    <Java编程思想>学习笔记(二)--类加载及执行顺序 (这是很久之前写的,保存在印象笔记上,今天写在博客上.) 今天看Java编程思想,看到这样一道代码 //: OrderOfIniti ...

  3. #Java编程思想笔记(一)——static

    Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ...

  4. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  5. JAVA编程讲座-吴老

    JAVA系列公开课第4讲:多态系列课程:从JAVA编程零基础讲起,同时结合工作中遇到的具体实例,语言清晰易懂,连续10周+深入讲解,打下编程基础,让我们一起打来自动化测试的大门时间:4月25日(周一) ...

  6. Google Java编程风格指南

    出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...

  7. 谷歌Java编程规范

    Google Java编程风格指南 January 20, 2014 作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声 ...

  8. Java编程中“为了性能”尽量要做到的一些地方

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  9. JAVA编程“性能说”(java编程需要做的26件事)

    转载于 http://www.csdn.net/article/2012-06-01/2806249 最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过 ...

随机推荐

  1. edraw mindmaster pro 8.1.0安装破解教程

    Edraw MindMaster Pro 8.1.0是一款思维导图(脑图)设计软件,头脑风暴.思维整理.项目策划.团队协作,多场景提升您的效率,功能齐全,个人觉得比xmind好用上手,文章手把手教你安 ...

  2. create-react-app 创建的项目执行npm run eject后,运行报错

    create-react-app 创建的项目执行npm run eject后,运行报错:Cannot find module '@babel/plugin-transform-react-jsx-so ...

  3. docker上运行mysql服务器

    1.搜索MySQL镜像 $ docker search mysql INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.i ...

  4. mysql orderby limit 翻页数据重复的问题

    在mysql中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页.但是,当limit遇到order by的时候,可能会 ...

  5. java方法基础

    java方法基础 方法的定义与调用 方法是命名的语句的有序集,是解决一类问题的步骤的有序组合. 方法包含于类或者是对象中,方法在程序中被创建,在其他地方被引用. 组成:方法是由方法头和方法体两部分组成 ...

  6. [JS]函数作为值

    在JavaScript中,函数不仅是语法,也是值.这意味着可以把函数赋值给变量.保存为对象的属性或者数组的元素.作为参数传给其他函数. 将函数赋值给变量s,实际上变量引用的是函数对象.不仅可以通过函数 ...

  7. 多线程案例:龟兔赛跑-Race

    多线程案例:龟兔赛跑-Race 前置条件: 首先来个赛道距离,然后要离终点越来越近 判断比赛是否结束 打印出胜利者 龟兔赛跑开始 故事中是乌龟赢了,兔子需要睡觉,所以我们来模拟兔子睡觉 乌龟赢得比赛 ...

  8. 遗传算法 TSP(Python代码)

    该代码是本人根据B站up主侯昶曦的代码所修改的. 原代码github地址:https://github.com/Houchangxi/heuristic-algorithm/blob/master/T ...

  9. 深入理解SPI机制

    一.什么是SPI SPI ,全称为 Service Provider Interface,是一种服务发现机制.它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加 ...

  10. 计算机毕业设计项目-基于SSM的学生会管理系统-基于ssm的社团信息管理系统

    注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM 前端技术:HTML+CSS+JavaScript+Bootstrap+jQuery 数据库: ...