【深入理解Java虚拟机】笔记6:自定义ClassLoader两种方式例子

版权声明:本文为个人学习总结,欢迎转载,转载时请附加原文链接 https://blog.csdn.net/cockroach02/article/details/88385455
一、重写findClass实现:
package com.example.jvm;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

public class NClassLoader extends ClassLoader {
	@Override
	public Class<?> findClass(String name) throws ClassNotFoundException {
		Class<?> clazz = findLoadedClass(name);
		if (clazz == null) {
			String filename = "D:\\workplaces\\demo\\target\\classes\\" + name.replace('.', File.separatorChar) + ".class";
			System.out.println(filename);
			try {
				FileInputStream fis = new FileInputStream(filename);
				FileChannel channel = fis.getChannel();
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				WritableByteChannel wChannel = Channels.newChannel(bos);
				ByteBuffer buffer = ByteBuffer.allocate(1024);
				while(true) {
					int i = channel.read(buffer);
					if (i == 0 || i == -1) {
						break;
					}
					buffer.flip();
					wChannel.write(buffer);
					buffer.clear();
				}
				fis.close();
				byte[] arr = bos.toByteArray();
				clazz = defineClass(name, arr, 0, arr.length);
			} catch (Exception e) {
				throw new ClassNotFoundException();
			}
		}
		return clazz;
	}
}
package com.example.jvm;

import java.util.ArrayList;
import java.util.List;

public class ClassLoaderTest {
	public static List<String> instance = new ArrayList<>();

	public static void main(String[] args) throws Exception {
		NClassLoader loader = new NClassLoader();
		Class<?> clazz = loader.findClass(ConstantClass.class.getCanonicalName());
		Object object = clazz.newInstance();
		System.out.println(object);
		System.out.println(object instanceof ConstantClass);
		System.out.println(instance instanceof List);
	}

}

二、重写loadClass实现
package com.example.jvm;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

public class NClassLoader2 extends ClassLoader {
	@Override
	public Class<?> loadClass(String name) throws ClassNotFoundException {
		Class<?> clazz = findLoadedClass(name);
		if (clazz != null) {
			return clazz;
		}
		if (!name.startsWith("com.example.jvm")) {
			return super.loadClass(name);
		}
		String filename = "D:\\workplaces\\demo\\target\\classes\\" + name.replace('.', File.separatorChar) + ".class";
		System.out.println(filename);
		try {
			FileInputStream fis = new FileInputStream(filename);
			FileChannel channel = fis.getChannel();
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			WritableByteChannel wChannel = Channels.newChannel(bos);
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			while(true) {
				int i = channel.read(buffer);
				if (i == 0 || i == -1) {
					break;
				}
				buffer.flip();
				wChannel.write(buffer);
				buffer.clear();
			}
			fis.close();
			byte[] arr = bos.toByteArray();
			return defineClass(name, arr, 0, arr.length);
		} catch (Exception e) {
			e.printStackTrace();
		}
		throw new ClassNotFoundException();
	}
}
package com.example.jvm;

import java.util.ArrayList;
import java.util.List;

public class ClassLoaderTest {
	public static List<String> instance = new ArrayList<>();

	public static void main(String[] args) throws Exception {
		NClassLoader2 loader = new NClassLoader2();
		Class<?> clazz = loader.loadClass(ConstantClass.class.getCanonicalName());
		Object object = clazz.newInstance();
		System.out.println(object);
		System.out.println(object instanceof ConstantClass);
		System.out.println(instance instanceof List);
	}
}

三、总结

推荐使用方式一

猜你喜欢

转载自blog.csdn.net/cockroach02/article/details/88385455