进阶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 ...
随机推荐
- MySQL所谓的脏页和“抖”一下是什么联系?
在我们平时经常用到的sql更新语句,之前是认为只要sql执行,当前sql的操作会立马执行到服务器磁盘上并返回,但是后来我才知道,事实并非如此,在了解事实之前,首先可能需要先了解什么是redo log, ...
- kotlin class
每个次构造函数需要委托给主构造函数, 可以直接委托或者通过别的次构造函数间接委托.委托到同一个类的另一个构造函数用 this 关键字即可 class Person { constructor(pare ...
- ios-动态添加方法,交换方法,重定向方法
新建一个类Person,Person.h 不写代码,Person.m 有如下两个方法: - (void)eat { NSLog(@"xxx eat===="); } [动态添加方法 ...
- GIT管理以及运行规范
继前天看分享的前后端分离后,又重新研究了GIT分支与各个环境的应用. 从开始使用git就一直有在网上查各种资料,查他的运行规范.但不知道是自己理解不够还是怎么的,一直用得不是很好. 根据自己的摸索,整 ...
- Understanding decimal(p, s) of sqlite3
带固定精度和小数位数的数值数据类型.decimal(p[ ,s]) 和 numeric(p[ ,s]) 固定精度和小数位数. 使用最大精度时,有效值的范围为 - 10^38 +1 到 10^38 - ...
- CentOS 7 最小化安装后的注意事项
http://blog.csdn.net/f_srion/article/details/54910943 在VM虚拟机中安装CentOS 7 时 有时候顾虑到电脑硬件性能,我们需要最小化安装,而最小 ...
- 一百一十四:CMS系统之图形验证码生成
安装Pillow库,用于生成图形验证码:pip install Pillow 字体文件来源 生成一个验证码图片 import randomimport stringfrom PIL import Im ...
- 一次神奇的JVM调优
老张接个新项目,项目可是不小,好多模块.使用Intellij import new project, 结果卡在writing class中,而且mac的风扇一直转,像是要变成直升机起飞. 等啊等,in ...
- EF中where中日期帅选问题
结合 SqlFunctions 和 DbFunctions 不能同时用两个DbFunctions queryAble = queryAble.Where(s=> SqlFunctions.D ...
- vue计算属性VS侦听属性
原文地址 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 Angular ...