ダークホースプログラマー-クラスローダ
クラス・ローダ:
JAva仮想マシンには複数のクラスローダがインストールされ、システムのデフォルトでは3つの主要なクラスローダがインストールされます.
各クラスは特定の場所のクラスをロードします:BootStrap,ExtClassLoader,AppClassLoader
クラスローダもjavaクラスですが、他のjavaクラスのクラスローダ自体もロードする必要があるので、
BootStrapというクラスローダはjavaクラスではなく、ローダの最上位として他のクラスローダをロードします.
JAva仮想マシンのクラスローダの管轄範囲:
BootStrap ----------> JRE/lib/rt.jar
ExtClassLoader ------->JRE/lib/ext/*.jar
AppClassLoader------>classpath指定パス上のすべてのjarまたはディレクトリ
クラスローダの委任メカニズム
1、現在のスレッドのクラスローダはスレッドの最初のクラスをロードします
2クラスAがクラスBを参照する場合、java仮想マシンはクラスAをロードするクラスローダを使用してクラスBをロードします.
3クラスローダを指定してクラスをロードするには、クラスローダを直接呼び出すこともできます.
4.各クラスローダがクラスをロードする時、またその上級クラスローダに依頼して、BootStrapをずっと上に見つけて、BootStrapがロードする場合
できなければ、下に戻り、最初に申請を提出するクラスローダまでロードできないと、異常を報告します:ClassNotFoundException
良い例はjava.lang.Systemというクラスを自分で書くことができるかどうかです.答えはいいですが、このクラスをロードしたのはBootStrapが直接
ロードシステムに付属するSystemクラス、すなわち、このクラスが書かれてもロードされません.自分でクラスローダを書いてこのクラスを専用にロードしない限り.
独自のクラス・ローダの作成
カスタムクラスローダはclassLoaderを継承し、findClassメソッドを書き換える必要があります.
手順:
1、ファイルの内容を簡単に暗号化するクラスを作成する
2、独自のクラスローダを作成し、暗号化されたクラスをロードして復号することができます.
3、プログラム呼び出しクラスローダを作成してクラスをロードします.ソースプログラムでは、コンパイラがこのクラスを認識できないため、クラス名で参照変数を定義できません.
プログラムではClassLoaderメソッドのほか、スレッドを設定するコンテキストクラスローダまたはシステムクラスローダを使用して、
class.forNameを使用します.
classファイルの暗号化を行うクラス
マイクラスローダ
テストクラス
JAva仮想マシンには複数のクラスローダがインストールされ、システムのデフォルトでは3つの主要なクラスローダがインストールされます.
各クラスは特定の場所のクラスをロードします:BootStrap,ExtClassLoader,AppClassLoader
クラスローダもjavaクラスですが、他のjavaクラスのクラスローダ自体もロードする必要があるので、
BootStrapというクラスローダはjavaクラスではなく、ローダの最上位として他のクラスローダをロードします.
JAva仮想マシンのクラスローダの管轄範囲:
BootStrap ----------> JRE/lib/rt.jar
ExtClassLoader ------->JRE/lib/ext/*.jar
AppClassLoader------>classpath指定パス上のすべてのjarまたはディレクトリ
クラスローダの委任メカニズム
1、現在のスレッドのクラスローダはスレッドの最初のクラスをロードします
2クラスAがクラスBを参照する場合、java仮想マシンはクラスAをロードするクラスローダを使用してクラスBをロードします.
3クラスローダを指定してクラスをロードするには、クラスローダを直接呼び出すこともできます.
4.各クラスローダがクラスをロードする時、またその上級クラスローダに依頼して、BootStrapをずっと上に見つけて、BootStrapがロードする場合
できなければ、下に戻り、最初に申請を提出するクラスローダまでロードできないと、異常を報告します:ClassNotFoundException
良い例はjava.lang.Systemというクラスを自分で書くことができるかどうかです.答えはいいですが、このクラスをロードしたのはBootStrapが直接
ロードシステムに付属するSystemクラス、すなわち、このクラスが書かれてもロードされません.自分でクラスローダを書いてこのクラスを専用にロードしない限り.
package com.east.firt;
public class ClassLoaderTest {
public static void main(String[] args){
System.out.println(
//
ClassLoaderTest.class.getClassLoader().getClass().getName()
);
System.out.println(
/*
* System , null,
* , BootStrap, java
* null
*/
System.class.getClassLoader()
);
ClassLoader loader = ClassLoaderTest.class.getClassLoader();
while(loader!=null){
//
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
}
}
独自のクラス・ローダの作成
カスタムクラスローダはclassLoaderを継承し、findClassメソッドを書き換える必要があります.
手順:
1、ファイルの内容を簡単に暗号化するクラスを作成する
2、独自のクラスローダを作成し、暗号化されたクラスをロードして復号することができます.
3、プログラム呼び出しクラスローダを作成してクラスをロードします.ソースプログラムでは、コンパイラがこのクラスを認識できないため、クラス名で参照変数を定義できません.
プログラムではClassLoaderメソッドのほか、スレッドを設定するコンテキストクラスローダまたはシステムクラスローダを使用して、
class.forNameを使用します.
classファイルの暗号化を行うクラス
import java.util.Date;
public class ClassAttatchment extends Date{
public String toString()
{
return "hello,itcast";
}
}
マイクラスローダ
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class MyClassLoader extends ClassLoader{
public static void main(String[] args) throws Exception{
String srcPath = args[0];
String destDir = args[1];
String fileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);
String destPath = destDir+"\\"+fileName;
FileInputStream fis = new FileInputStream(srcPath);
FileOutputStream fos = new FileOutputStream(destPath);
cypher(fis,fos);
fis.close();
fos.close();
}
// , 255
private static void cypher(InputStream ips,OutputStream ops)throws Exception{
int b = 0;
while((b=ips.read())!=-1){
ops.write(b ^ 0xff);
}
}
private String classDir;
// findClass , class
@Override
protected Class> findClass(String name) throws ClassNotFoundException {
String classFileName = classDir + "\\" + name.substring(name.lastIndexOf('.')+1) + ".class";
try {
FileInputStream fis = new FileInputStream(classFileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
cypher(fis,bos);
fis.close();
byte[] bytes = bos.toByteArray();
return defineClass(null,bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}
public MyClassLoader(){
}
public MyClassLoader(String classDir){
this.classDir = classDir;
}
}
テストクラス
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
public class ClassLoaderTest extends ClassLoader{
public static void main(String[] args) throws Exception{
Class clazz = new MyClassLoader("itcastlib").loadClass("cn.it.cast.ClassAttatchment");
Date d = (Date)clazz.newInstance();
System.out.println(d);
}
}