ダークホースプログラマー-クラスローダ


クラス・ローダ:
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);  
    }     
}