进阶Java编程(11)ClassLoader类加载器【待完成】
1,ClassLoader类加载器简介
在Java里面提供一个系统的环境变量:ClassPath,这个属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指定路径中类的加载,也就是说找到了类的加载器就意味着找到了类的来源。
系统类的加载器
如果说现在要想获得类的加载器,那么一定要通过ClassLoader来获取,而要想获取ClassLoader类的对象,则必须利用class类【反射的根源】实现,方法:public ClassLoader getClassLoader(),当获取了ClassLoader之后还可以继续获取其父类的ClassLoader类对象:public final ClassLoader getParent();
·范例:观察类加载器
class Message {
}
public class JavaAPIDemo {
public static void main(String[] args) {
Class<?> clazz=Message.class;
System.out.println(clazz.getClassLoader());//获取当前类的加载器
System.out.println(clazz.getClassLoader().getParent());//获取父类加载器
System.out.println(clazz.getClassLoader().getParent().getParent());//获取祖父类加载器
}
}
/*
jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
jdk.internal.loader.ClassLoaders$PlatformClassLoader@1e643faf
null
*/
从JDK1.8之后的版本【JDK1.9和JDK1.10】提供有一个【PlatformClassLoader】类加载器,而在JDK1.8以及以前的版本里面提供的加载器为【ExtClassLoader】,因为在JDK的安装目录里面提供又一个ext的目录,开发者可以将【*.jar】文件拷贝到此目录里面,这样就可以直接执行了,但是这样的处理开发并不安全,最初的时候也是不提倡使用的,所以从JDK1.9开始将其彻底废除,同时为了和系统加载器与应用类加载器之间保持设计的平衡,提供有平台类加载器。
当你获得了类加载器之后就可以利用类加载器来实现类的反射加载处理。
2,自定义ClassLoader处理
清楚了类加载器的功能之后,就可以根据自身的需要实现自定义的类加载器,但是千万要记住一点:自定义类加载器其加载的顺序是在所有系统类加载器的最后。系统类中的加载器都是根据CLASSPATH找到的路径进行类加载的,而如果有了自定义类的加载器,就可以由开发者任意指派类的加载位置。
①随意编写一个程序类,并且将这个类保存在磁盘上;
import java.io.*; public class MufasaClassLoader extends ClassLoader {
private static final String MESSAGE_CLASS_PATH="D:"+ File.separator+"Message.class";
/**
* 进行指定类的加载
* @param className 类的完整名称【包.类】
* @return 返回一个指定类的class对象
* @throws Exception 如果类文件不存在则无法加载
*/
public Class<?> loadData(String className)throws Exception{
byte[] data=this.loadClassData();//读取二进制数据文件
if(data!=null){//读取到数据
return super.defineClass(className,data,0,data.length);
}
return null; }
private byte[] loadClassData()throws Exception{//通过文件进行类的加载
InputStream input=null;
ByteArrayOutputStream bos=null;//将数据加载到内存之中
byte[] data=null;
try{
bos=new ByteArrayOutputStream();//实例化内存流
input=new FileInputStream(new File(MESSAGE_CLASS_PATH));//文件流加载
// byte[] data=new byte[1024];//进行读取方式①
input.transferTo(bos);//读取数据方式②
data= bos.toByteArray();//将所有读取到的字节数组取出
}catch (Exception e){ }finally {
if(input!=null){
input.close();
}
if(bos!=null){
bos.close();
}
}
return data;
}
}
④编写测试类实现类加载控制;
package cn.mufasa.demo;
import cn.mufasa.util.MufasaClassLoader;
import java.lang.reflect.Method; public class JavaAPIDemo1 {
public static void main(String[] args) throws Exception {
MufasaClassLoader classLoader=new MufasaClassLoader();
Class<?> cls=classLoader.loadData("cn.mufasa.util.Message");//进行类的加载
System.out.println(cls);
Object obj=cls.getDeclaredConstructor().newInstance();
Method method=cls.getDeclaredMethod("send");
method.invoke(obj);
}
}
/*
读取到数据
class cn.mufasa.util.Message
www.cnblogs.com
*/
如果在以后结合网络开发的话,就可以通过一个远程的服务器来确定类的功能。
⑤观察当前的Message类的加载器的情况
package cn.mufasa.demo;
import cn.mufasa.util.MufasaClassLoader;
import java.lang.reflect.Method; public class JavaAPIDemo1 {
public static void main(String[] args) throws Exception {
MufasaClassLoader classLoader=new MufasaClassLoader();
Class<?> cls=classLoader.loadData("cn.mufasa.util.Message");//进行类的加载
// System.out.println(cls);
System.out.println(cls.getClassLoader());//获取当前类的加载器
System.out.println(cls.getClassLoader().getParent());//获取父类加载器
System.out.println(cls.getClassLoader().getParent().getParent());//获取祖父类加载器 }
}
/*
cn.mufasa.util.MufasaClassLoader@668bc3d5
jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
jdk.internal.loader.ClassLoaders$PlatformClassLoader@3fb6a447
*/
如果说你先在定义了一个类,这个类的名称定义为:java.lang.String,并且利用了自定义类加载器进行加载处理,这个类将不会被加载,原因:Java之中针对于类加载器提供有双亲加载机制,如果现在要加载的类是由系统提供的类则会由系统类进行加载,如果现在开发者定义的类与系统类定义的名称相同,那么【为了保证系统的安全性】绝对不会加载。
进阶Java编程(11)ClassLoader类加载器【待完成】的更多相关文章
- Java安全之 ClassLoader类加载器
Java安全之 ClassLoader类加载器 0x00 前言 前面这里抛出一个问题,Java到底是什么类型的编程语言?是编译型?还是解释型?在这个问题是其实一直都都有疑惑,如果说是解释型语言的话,那 ...
- Java URLClassLoader 和 ClassLoader类加载器
开始:看名字都带有ClassLoader,叫做类加载器,事实上是可以理解为动态的加载类,不过,也不是只能加载类,也可以加载其他形式的文件,比如说.properties属性文件. 区别:其实在两个类加载 ...
- Java中对于ClassLoader类加载器 嵌套了深度技术的价值
关于Java技术是一种不断兴起的编程语言,对于ClassLoader 是 Java 届最为神秘的技术之一,无数人被它伤透了脑筋,摸不清门道究竟在哪里.本文我带你彻底吃透 ClassLoader,让你甚 ...
- 【原创】Java基础之ClassLoader类加载器简介
classloader简介 1 classloader层次结构(父子关系) Bootstrap(ClassLoader) ExtClassLoader AppClassLoader XXXClassL ...
- ClassLoader类加载器 & Java类加载机制 & 破坏双亲委托机制
ClassLoader类加载器 Java 中的类加载器大致可以分成两类: 一类是系统提供的: 引导类加载器(Bootstrap classloader):它用来加载 Java 的核心库(如rt.jar ...
- 万万没想到,面试中,连 ClassLoader类加载器 也能问出这么多问题…..
1.类加载过程 类加载时机 「加载」 将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存上创建一个java.lang.Class对象用来封装类在方法区内的数据 ...
- 【Java虚拟机3】类加载器
前言 Java虚拟机设计团队有意把类加载阶段中的"通过一个类的全限定名来获取描述该类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需的类. ...
- java ClassLoader类加载器
原文 首先来了解一下字节码和class文件的区别: 我们知道,新建一个java对象的时候,JVM要将这个对象对应的字节码加载到内存中,这个字节码的原始信息存放在classpath(就是我们新建Java ...
- java 反射,类的加载过程以及Classloader类加载器
首先自定义一个类Person package reflection; public class Person { private String name; public int age; public ...
随机推荐
- buff/cache占用过高的问题
工作记录 > /proc/sys/vm/drop_caches 默认是0,不清除缓冲区缓存和页面缓存 可用值 0 到 3 值越高系统上的程序会跑起来越慢 free -m 蛋疼的是这只是一次性的, ...
- SPOJ AMR12B 720
这个题应该是个优先队列的模版题 当时比赛的时候没时间做先贴一下大神的代码好好学习学习 B - Gandalf vs the Balrog Time Limit:2000MS Memory Li ...
- zabbix自定义监控,自定义图表。
zabbix server:hostname=Zabbix server ip:192.168.100.7 zabbix agent: hostname=host3 ip:192.168.100.3 ...
- shell 拾遗
1, 按照行读取文件 while read line do echo ${line} done < ${filename} 2.循环中使用命令输出 while read line do echo ...
- ObjectAnimator属性动画示例代码
import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.app.Ac ...
- kafka整合springboot
1.pom.xml添加依赖 <dependency> <groupId>org.springframework.kafka</groupId> <artifa ...
- tomcat简单快捷改端口
- 【分布式事务】使用atomikos+jta解决分布式事务问题
一.前言 分布式事务,这个问题困惑了小编很久,在3个月之前,就间断性的研究分布式事务.从MQ方面,数据库事务方面,jta方面.近期终于成功了,使用JTA解决了分布式事务问题.先写一下心得,后面的二级提 ...
- 数据库文件结构、sqlserver ON [PRIMARY]
在sqlserver创建表的语句中,最后总来一句on[primary],这到底是什么意思? .联机丛书中CREATE TABLE的语法下似乎没有找到.最后终于发现,具体如下: 在CREATE TABL ...
- python基础知识(函数2)
返回值 return return[value] 多个值用,逗号分开,没有返回值,会返回none值,函数不给指定返回值也会返回none值 def functionname(p1,p2,p3): re ...