java ClassLoader机制和如何加载外部class文件(含代码)

Java类的生命周期

生命周期有:加载(Loading)--》验证(Verification)--》准备(Preparation)---》解析(Resolution)--》初始化(Initiation)---》使用(Using)----》卸载(Unloading)。
其中标黄的验证---》准备---》解析被称为连接(Linking)。

就代码执行而言:

1.连接阶段:不执行程序员代码

2.加载阶段:可以重写ClassLoader来执行我们的代码

3.连接后阶段:执行该类的代码

ClassLoader:

ClassLoader是为了将class文件的byte数组,主要的方法是findClass用于查找类。

Java7有个迅速将File编程byte[]的方法:

		byte[] cLassBytes = null;
		Path path;
		try {
			path = Paths.get(new URI("file:///D:/MyScript/TestClassLoader.class"));
			cLassBytes = Files.readAllBytes(path);

每个ClassLoader对象都有一个ClassLoader类型的字段,暂且成为parent。当调用本类的loadClass方法加载类时,会先调用parent的ClassLoader,如果他没找到,才会调用本类的findClass方法去查找类。(这样,应用的Launcher$AppClassLoader也可以通过BootStrapClassLoader来调用String类了)。

查找类的顺序,与对应的ClassLoader

系统查找类的顺序是:

1).Bootstrap classes: the runtime classes in rt.jar,
internationalization classes in i18n.jar, and others.

2).Installed extensions: classes in JAR files in the lib/ext directory
of the JRE, and in the system-wide, platform-specific extension directory (such as /usr/jdk/packages/lib/ext on
the Solaris? Operating System, but note that use of this directory applies only to Java? 6 and later).

3).The class path: classes, including classes in JAR
files, on paths specified by the system property java.class.path. If a JAR file on the class
path has a manifest with the Class-Path attribute,
JAR files specified by the Class-Path attribute
will be searched also. By default, thejava.class.path property‘s
value is ., the current directory. You can
change the value by using the -classpath or -cp command-line
options, or setting the CLASSPATH environment
variable. The command-line options override the setting of the CLASSPATH environment
variable.

中文就是:

1)rt.jar等(这个jar是什么呢?你用java -verbose 类名 运行下就看到了:Loaded java.io.File from C:\Program Files\Java\jre1.8.0_31\lib\rt.jar,也就是经常调用的String、Long等类,属于SDK中的)(用BootStrapClassLoader加载)

2) SDK中的拓展类,包名为javax的(java和javax都是Java的API(Application
Programming Interface)包,java是核心包,javax的x是extension的意思);

(用Launcher$ExtClassLoader加载)

3) 系统环境变量CLASSPATH的路径,当前目录(或者用命令行带 -classpath重新)

(用Launcher$AppClassLoader加载)

可是我的类文件在D:\MyScript\TestClassLoader.class不在上述三种。

2:解决方案

1.场景:我想加载一个d盘上的类,路径是:D:\MyScript\TestClassLoader.class,其不在上述三种情况。

通过重写一个ClassLoader进行加载,不过有现成的URLClassLoader我们就不要重造轮子了。

自定义ClassLoader代码

public class MyClassLoader extends ClassLoader{

	@Override
	protected Class<?> findClass(String className)
			throws ClassNotFoundException {
		byte[] cLassBytes = null;
		//Java 7有下列API
<span style="white-space:pre">		</span>Path path;
		try {
			path = Paths.get(new URI("file:///D:/MyScript/TestClassLoader.class"));
			cLassBytes = Files.readAllBytes(path);
		} catch (IOException | URISyntaxException e) {
			e.printStackTrace();
		}
		Class cLass = defineClass(cLassBytes, 0, cLassBytes.length);
		return cLass;
	}
}

使用的时候:

			Class.forName("TestClassLoader", true, new MyClassLoader());

用URLClassLoader来简化

		  ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

		    // This URL for a directory will be searched *recursively*
		    URL classes;
			try {
				classes = new URL( "file:///D:/MyScript/" );

		    ClassLoader custom =
		        new URLClassLoader( new URL[] { classes }, systemClassLoader );

		    // this class should be loaded from your directory
		    Class< ? > clazz = custom.loadClass( "TestClassLoader" ); 

		    Method[] methods = clazz.getDeclaredMethods();
		    for (Method method : methods) {
				System.out.println(method.getName());
			}

URLClassLoader用的URL只能接受目录和jar包:

结尾: /代表该目录下的来; 非/而是文件则默认为jar包。

贴一个jar包的代码:

public URL findResource(String name) {
try {
File file = new File(jarFile);
String url = file.toURL().toString();
return new URL("jar:"+url+"!/"+name);
} catch (Exception e) {
return null;
}

}<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">	</span>

另外我用反射来验证类是否加载成功了,clazz.newInstance()也可以生成相关代码。

时间: 2024-11-10 11:29:15

java ClassLoader机制和如何加载外部class文件(含代码)的相关文章

JBoss 系列十四:JBoss7/WildFly如何加载外部的文件或properties文件

http://www.tuicool.com/articles/M7ZR3y 原文 http://blog.csdn.net/kylinsoong/article/details/12623997 主题 WildFlyXMLJBoss AS 内容概述 JBoss7/WildFly设底层框架一大亮点的Module class loading,及每一个相对独立的模块看作一个Module,每个Module都有自己的class loader,Module之间可以相互依赖,如下图: 当JBoss7安装完成

使用js加载器动态加载外部Javascript文件

今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js 1 var MiniSite=new Object(); 2 /** 3 * 判断浏览器 4 */ 5 MiniSite.Browser={ 6 ie:/msie/.test(window.navigator.userAgent.toLowerCase()), 7 moz:/gecko/.test(window.navigator.userAgent.toLowerCase()), 8 opera:/o

Vue 加载外部js文件

Vue.js  加载外部js文件 在项目内新建一个config.js //变量的定义 export var config = { baseurl:'http://172.16.114.5:8088/MGT2' } //函数的定义 export function formatXml(text) { return text } 使用外部的js <script> import {config,formatXml} from '../static/config.js' export default {

PhoneGap 白名单安全机制 navigator.app 加载外部页面返回以及退出介绍

一. Phonegap 白名单安全机制 Phonegap应用的页面大多存在于本地,但有时需要加载外部的Web页面到应用内置的浏览器 视图中已完成特定的应用功能,出于安全性考虑,PhoneGap 设立了白名单安全机制,通过它来 控制能够加载到内置浏览器视图的内容来源. Android 不通过白名单安全机制的话调用外部浏览器 IOS 不通过白名单安全的话 会直接拒绝 二.Android 配置白名单 在res/xml/config.xml这个文件里进行配置 三.IOS 配置 以及 Wp7/wp8配置白

PhoneGap 白名单安全机制 navigator.app 加载外部页面返回

学习要点: 1. Phonegap 白名单安全机制 2. Navigator.app 对象加载外部页面 返回上级页面 一. Phonegap 白名单安全机制 Phonegap应用的页面大多存在于本地,但有时需要加载外部的Web页面到应用内置的浏览器 视图中已完成特定的应用功能,出于安全性考虑,PhoneGap 设立了白名单安全机制,通过它来 控制能够加载到内置浏览器视图的内容来源. Android 不通过白名单安全机制的话调用外部浏览器 IOS 不通过白名单安全的话会直接拒绝. Android

java 反射机制与动态加载类学习要点

获取Class类的对象: 假设Foo是一个类,Foo foo = new Foo():则 第一种:Class c1 = Foo.class; 第二种:Class c2 = foo.getClass(); 第三种:Class c3 = Class.forName("com.nudt.reflection.Foo"); //会抛出异常 此时  c1 == c2 == c3 为true 也可以通过c1\c2\c3创建Foo的实例: Foo foo = (Foo)c1.newInstance(

kettle转换JavaScript加载外部js文件

日常开发中,时常会出现这样一种情况.有大量的函数是通用的.而每个JavaScript里面写一遍,给维护带来很大的困扰.因而需要将公共的函数写在外部js文件中.这时就需要引入外部的公共文件了.下面是在转换里的JavaScript组件中引入外部公共js文件. //加载js文件 LoadScriptFile(getVariable("Internal.Transformation.Filename.Directory", "") +"/common_Functi

应用程序加载外部字体文件(使用AddFontResource API函数指定字体)

[cpp] view plain copy /* MSDN: Any application that adds or removes fonts from the system font table should notify other windows of the change by sending a WM_FONTCHANGE message to all top-level windows in the operating system. The application should

深入java虚拟机学习 -- 类的加载机制(续)

昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: class Singleton { private static Singleton singleton = new Singleton(); //第一份代码的位置 public static int counter1; public static int counter2=0; private s