java 类加载与自定义类加载器详解
作者:郑宏鑫erke 发布时间:2022-05-21 04:31:31
标签:java,类加载
类加载
所有类加载器,都是ClassLoader的子类。
类加载器永远以.class运行的目录为准。
读取classpath根目录下的文件有以下几种方式:
1 在Java项目中可以通过以下方式获取classspath下的文件:
public void abc(){
//每一种读取方法,使用某个类获取Appclassloader
ClassLoader cl = ReadFile.class.getClassLoader();
URL url = cl.getResource("a.txt");
System.err.println("url1 is:"+url.getPath());
//第二种方式,直接使用ClassLoader
URL url2 = ClassLoader.getSystemResource("a.txt");
System.err.println("url2 is:"+url2.getPath());
}
在Tomcat中tomcat又声明了两个类载器:
StandardClassLoader– 加载tomcat/lib/*.jar - serlvetapi.jar
Webappclassloader /加载 tomcat/webapps/project/web-inf/lib/*.jar && web-inf/classes/*.class
在任何的项目中,获取类的加载器都应该使用以下方式:
SomeClass(你写的).class.getClassLoader().getResource ;获取到这个类的类加载器
在java项目中是:AppClassLoader
在Web项目中:WebAppClassLoader
测试父类加载器:
public class OneServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ClassLoader loader = OneServlet.class.getClassLoader();//WebAppClassLoader
int index=1;
while(loader!=null){
System.err.println((index++)+"类加载器是:"+loader.getClass());
loader=loader.getParent();//获取父类加载器
}
}
}
运行的结果:
1类加载器是:class org.apache.catalina.loader.WebappClassLoader
2类加载器是:class org.apache.catalina.loader.StandardClassLoader
3类加载器是:class sun.misc.Launcher$AppClassLoader
4类加载器是:class sun.misc.Launcher$ExtClassLoader
自定义类加载器
JDK以哪一个类加载器读取A类的字节码,则A类就是被哪一个类加载器加载 的。
一个同名的类,是否可以相互转换,要看是否是在同个类加载器中。
package cn.hx.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
public class MyClassLoader2 extends ClassLoader {
/**
* name:cn.itcast.demo.Person
* 根据包名找到.class文件
* cn.itcast.demo.person = > cn/itcast/demo/Person.class
*/
public Class<?> findClass(String name ) throws ClassNotFoundException {
String classNameWithPackage=name;
Class<?> cls = null;
try {
//先将
name = name.replace(".","/");
name +=".class";
//确定目录
URL url = MyClassLoader2.class.getClassLoader().getResource(name);
System.err.println(">>:"+url.getPath());
File file = new File(url.getPath());
InputStream in = new FileInputStream(file);
//读取这个.class文件的字节码
byte[] b = new byte[in.available()];//直接声明这个字节大小为这个文件的大小
int len = in.read(b);//len=621
System.err.println(len);
/**
* 第一个参数是类名
*/
cls = defineClass(classNameWithPackage,b,0,len);
} catch (Exception e) {
e.printStackTrace();
}
return cls;
}
}
测试类自定义类加载器
public class ClassLoaderDemo {
public static void main(String[] args) throws Exception {
MyClassLoader2 mc = new MyClassLoader2();
Class cls = mc.findClass("cn.itcast.demo.Person");
Object o = cls.newInstance();
System.err.println("toString:"+o+","+o.getClass().getClassLoader());
//直接使用peron是 AppClassLoader
System.err.println(">>:"+Person.class.getClassLoader());
//由于o是由mc加载的。而Person是由App加载的,所有不可以转换=来自于两个不同的加载器
//Person p = (Person) o;//类型转换错误ClassCastException
//System.err.println(p);
}
}
来源:http://www.cnblogs.com/zhenghongxin/p/4519438.html


猜你喜欢
- 一、数组与数组元素Java中数组是引用类型数组的元素可以是基本类型也可以是引用类型,弄清数组元素的类型可以帮助我们去理解数组元素默认初始化二
- 一、题目描述题目:有五个学生,每个学生有 3 门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),把这些数据存放在磁盘文件 &q
- 概念Drawable表示一种可以在Canvas上进行绘制的抽象的概念,它有很多种,常见的如颜色和图片都可以是一个Drawable。优点首先,
- 前言:在android HTML5 开发中有不少人遇到过 audio 标签 autoplay在某些设备上无效的问题,网上大多是讲怎么在js中
- 使用Castle.Core.dll实现,核心代码是使用Castle.DynamicProxy.ProxyGenerator类的CreateI
- FROM子句一、简单FROM子句获取数据源:var queryAllCustomers = &nb
- android 在webView里面截图大概有四种方式,具体内容如下1.获取到DecorView然后将DecorView转换成bitmap然
- 本文实例为大家分享了Android项目实现视频播放器的具体代码,供大家参考,具体内容如下VideoView控件是播放视频用的,借助它可以完成
- 根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要
- 前面文章介绍了Android利用麦克风采集并显示模拟信号的实现方法,这种采集手段适用于无IO控制、单纯读取信号的情况。如果传感器本身需要包含
- 一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对
- Scala小程序详解1. 交互式模式在命令行窗口中,输入Scala命令:xiaosi@Qunar:~$ scalaWelcome to S
- 关联篇:HandlerThread 使用及其源码完全解析关联篇:Handler内存泄漏详解及其解决方案一说到Android的消息机制,自然就
- Collectors.toMap空指针问题在工作中遇到了一个List转Map的时候的一个NullPointException.情形很简单,问
- Java continue break 制作简单聊天室程序,屏蔽不文明语言,显示每句话聊天时间package com.swift;impor
- 在工作中要求将图片上传至本地,如下代码将介绍如何将图片上传至本地准备工作:环境:eclipse4.5-x64,jdk1.7-x64,mave
- 正则表达式 是一种匹配输入文本的模式。.Net 框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。接下来通过本
- 同步代码块基本语句synchronized (任意对象) {操作共享代码}代码示例public class SellTicket imple
- 1、谷歌浏览器配置管理在代理服务器中,按上图进行设置,可以把localhost换成 127.0.0.1 ,端口换成你想设置的,但是不要与别的
- 使用udp实现消息的接收和发送代码比较简单,但是别忘记关闭防火墙进行测试。首先便是服务端,使用Socket进行实现,参考代码如下: