进阶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 ...
随机推荐
- LeetCode109----链表转为二叉搜索树
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例:给定的有序链表: [-10, ...
- 对于join操作,MySQL它是咋做的?
首先我们对于join操作,需要了解两个概念:驱动表和被驱动表.首先先给出两张表: CREATE TABLE `t2` ( `id` ) NOT NULL, `a` ) DEFAULT NULL, `b ...
- 微信小程序swiper禁止用户手动滑动
最近做一个项目,由于用到了竖向swiper,导致占用屏幕过大,用户滑动总是滑动到swiper组件,页面无法向下拉动,于是找各种办法禁止用户手动滑动swiper组件. 经过网上一番查找,网友们也是闹洞大 ...
- tensorflow训练中出现nan
问题暂记: 之后看 https://blog.csdn.net/qq_23142123/article/details/80526931 https://www.zhihu.com/question/ ...
- java调用exe,及调用bat不成功的解决办法
开门见山的说,文件目录如下 想调用123.exe,但是尝试了几次调用不到,然后写了个bat.初始内容如下 @echo off D: cd test "123.exe" 双击可以运行 ...
- RecyclerView只有一行
RecyclerView只有一行 方法1: 将RecyclerView放在父容器RelativeLayout中,并设置RelativeLayout属性 android:descendantFocu ...
- 前端知识点回顾之重点篇——ES6的Promise对象
Promise Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异 ...
- [go]os/exec执行shell命令
// exec基础使用 import ( "os/exec" ) cmd = exec.Command("C:\\cygwin64\\bin\\bash.exe" ...
- 面向对语法读取mysql数据库数据例:$db->query($sql)、$result->fetch_array()
前面我们介绍过如何使用面向对象语法连接mysql数据库,今天技术人员继续讲解如何读取数据.虽然与以前面向过程类似,但还是有些不同,需要大家用心了解. echo '面向对象语法连接数据库test db ...
- 一百二十:CMS系统之注册功能前后端逻辑
给提交按钮加一个id,方便写js js //发送ajax请求注册请求$(function () { $('#submit-btn').click(function (event) { event.pr ...