自定义类加载器
继承ClassLoader类,重写里面的findClass方法。 另写一个方法获取.Class/Xlass文件中的二进制数,以数组方式存储返回。
调用父类的defineClass方法,返回一个类。
此处的xlass文件是取反加密后的文件。所以在获取数组的时候,有一个遍历取反。
import java. io. ByteArrayOutputStream;
import java. io. FileInputStream;
import java. io. FileNotFoundException;
import java. io. IOException;
public class MyClassLoader extends ClassLoader {
@Override
protected Class< ? > findClass ( String name) throws ClassNotFoundException {
Class log = null;
byte [ ] classData = getData ( ) ;
if ( classData != null) {
log= defineClass ( name, classData, 0 , classData. length) ;
}
return log;
}
public byte [ ] getData ( ) {
FileInputStream inputStream = null;
ByteArrayOutputStream byteArrayOutputStream = null;
try {
inputStream = new FileInputStream ( "C:\\Users\\DELL\\Desktop\\商城项目\\untitled\\src\\Hello.xlass" ) ;
byteArrayOutputStream= new ByteArrayOutputStream ( ) ;
byte [ ] data = new byte [ 1024 ] ;
byte [ ] data2 = new byte [ 1024 ] ;
int size;
while ( ( size = inputStream. read ( data) ) != - 1 ) {
for ( int i = 0 ; i < size ; i++ ) {
data[ i] = ( byte ) ( ~ data[ i] ) ;
}
byteArrayOutputStream. write ( data, 0 , size) ;
}
} catch ( FileNotFoundException e) {
e. printStackTrace ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
return byteArrayOutputStream. toByteArray ( ) ;
}
}
利用反射机制,获取类和方法。
jdk9之后废弃了newInstance方法,故采用Class.forName(“name”,Boolean,ClassLoader)的方法获取类对象并初始化
但是此处的newInstance方法被废除,在注释中找到其替代方法 Hello.getDeclaredConstructor().newInstance()。
import java. lang. reflect. Method;
public class Test {
public static void main ( String[ ] args) throws Exception {
MyClassLoader myClassLoader = new MyClassLoader ( ) ;
myClassLoader. findClass ( "Hello" ) ;
Class< ? > Log = myClassLoader. loadClass ( "Hello" ) ;
Method hello = Log. getDeclaredMethod ( "hello" , null) ;
Class< ? > Hello = Class. forName ( "Hello" , true , myClassLoader) ;
hello. invoke ( Hello. getDeclaredConstructor ( ) . newInstance ( ) ) ;
}
}
D: \Java\jdk- 9 \bin\java. exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=49683:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin" - Dfile. encoding= UTF- 8 - classpath C: \Users\DELL\Desktop\商城项目\untitled\out\production\untitled Test
Hello, classLoader!
Process finished with exit code 0