자바 클래스 로 더 학습 2 - 사용자 정의 클래스 로 더 와 부모 클래스 의뢰 메커니즘 에 따 른 문제

6182 단어 자바
1. 사용자 정의 클래스 로 더 의 일반적인 절차
자바 의 클래스 로 더 는 JDK 1.2 부터 부모 클래스 의뢰 체제 라 는 메커니즘 을 도입 했다.클래스 가 불 러 올 때 JVM 은 먼저 부모 클래스 로 더 를 불 러 옵 니 다. 부모 클래스 는 부모 클래스 의 부모 클래스 를 불 러 옵 니 다. 최상 위 클래스 로 더 를 불 러 옵 니 다.부모 클래스 로 더 를 불 러 올 수 없다 면 하위 클래스 를 사용 하여 불 러 옵 니 다.물론 이런 부류 가 말 하 는 부류 의 캐리어 는 반드시 그들 사이 가 계승 하 는 관계 가 아니 라 포장 의 관계 일 수도 있다.
자바 가 이 메커니즘 을 등장 시 킨 이 유 는 안전성 을 고려 하고 있 기 때문이다.사용자 가 클 라 스 파일 을 정의 하고 클래스 로 더 를 써 서 JVM 이 직접 불 러 올 클래스 를 불 러 올 까 봐 두 렵 습 니 다.이렇게 하면 JVM 가상 컴퓨터 가 혼 란 스 럽 거나 사용자 의 안전 에 영향 을 줄 수 있다.다음은 클래스 로 더 를 계승 하 는 클래스 로 더 를 스스로 실현 합 니 다.우 리 는 이해 할 필요 가 있다.
대부분의 경우 시스템 이 기본적으로 제공 하 는 클래스 로 더 는 수 요 를 만족 시 킬 수 있 습 니 다.그러나 어떤 경우 에는 응용 을 위해 자신의 클래스 로 더 를 개발 해 야 합 니 다.예 를 들 어 네트워크 를 통 해 자바 류 의 바이트 코드 를 전송 하고 안전성 을 확보 하기 위해 이 바이트 코드 들 은 암호 화 처 리 를 거 쳤 습 니 다.이 럴 때 암호 화 된 바이트 코드 를 네트워크 주소 에서 읽 고 복호화 와 검증 을 한 다음 자바 가상 컴퓨터 에서 실행 할 클래스 를 정의 해 야 합 니 다.다음은 두 개의 구체 적 인 실례 를 통 해 클래스 캐리어 의 개발 을 설명 할 것 이다.
① ClassLoader 로 딩 클래스 의 순서
1. findLoadedClass (String) 를 호출 하여 클래스 를 불 러 왔 는 지 확인 합 니 다.
2. 부모 클래스 로 더 에서 loadclash 방법 을 호출 합 니 다.아버지 가 불 러 올 수 없다 면, 한 번 에 한 단계 씩 하위 클래스 에 전달 합 니 다.
3 하위 클래스 findClass (String) 방법 으로 클래스 를 찾 습 니 다.불 러 올 수 없 으 면 ClassNotFoundException 으로 돌아 가 요청 한 로 더 의 하위 로 더 에 맡 기지 않 습 니 다.
② 자신의 클래스 로 더 구현
1 클래스 클래스 파일 을 가 져 오 는 바이트 그룹, 예 를 들 어 loadClassData 방법
2 바이트 배열 을 Class 클래스 의 인 스 턴 스 로 바 꾸 고 findClass 에서 호출 된 defineClass 방법 을 다시 씁 니 다.
package cn.M_ClassLoader2;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;


public class ClassLoaderTest
{
	public static void main(String[] args) throws InstantiationException, IllegalAccessException,  ClassNotFoundException
	{
		//         
		MyClassLoader cl = new MyClassLoader("myClassLoader");
		
		//    ,  Class  
		Class<?> clazz = cl.loadClass("cn.M_ClassLoader2.Animal");
		
		//       
		Animal animal = (Animal) clazz.newInstance();
		animal.say();
	}
}

class Animal
{
	public void say()
	{
		System.out.println("hello world!");
	}
}

class MyClassLoader extends ClassLoader
{
	//        
	private String name;
	
	//       
	private String path = MyClassLoader.getSystemClassLoader().getResource("").getPath();;

	MyClassLoader(String name)
	{
		this.name = name;
	}

	MyClassLoader(ClassLoader parent, String name)
	{
		super(parent);
		this.name = name;
	}

	/**
	 *   findClass  
	 */
	@Override
	public Class<?> findClass(String name)
	{
		byte[] data = loadClassData(name);
		return this.defineClass(name, data, 0, data.length);
	}

	public byte[] loadClassData(String name)
	{
		try
		{
			name = name.replace(".", "//");
			FileInputStream is = new FileInputStream(new File(path + name + ".myclass"));
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int b = 0;
			while ((b = is.read()) != -1)
			{
				baos.write(b);
			}
			System.out.println("          !");
			return baos.toByteArray();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
}
 


일반적으로 자신 이 개발 한 클래스 로 더 는 복사 findClass(String name) 방법 만 있 으 면 된다.java.lang.ClassLoader 류 의 방법 loadClass() 은 앞에서 언급 한 대리 모델 의 실현 을 밀봉 했다.이 방법 은 먼저 findLoadedClass() 방법 을 호출 하여 이 종류 가 불 러 왔 는 지 확인 합 니 다.불 러 오지 않 았 다 면 부모 클래스 로 더 loadClass() 방법 으로 이 종 류 를 불 러 오 려 고 시도 합 니 다.부모 클래스 로 더 가 이 종 류 를 불 러 올 수 없다 면 findClass() 방법 으로 이 종 류 를 찾 습 니 다.따라서 클래스 로 더 가 프 록 시 모델 을 정확하게 실현 할 수 있 도록 자신의 클래스 로 더 를 개발 할 때 덮어 쓰 기 loadClass() 방법 이 아니 라 덮어 쓰 기 findClass() 방법 이 좋 습 니 다.
질문
findClass 방법 만 다시 썼 을 뿐 loadClass 방법 을 다시 쓰 지 않 았 기 때문에 부모 클래스 의뢰 체 제 를 바 꾸 지 않 았 습 니 다.어떤. class 가 부모 클래스 에 불 러 올 수 있다 면 사용자 정의 클래스 로 더 는 실행 되 지 않 을 것 입 니 다.예 를 들 어 Animal. java 는 Animal. class 로 자동 으로 컴 파일 되 어 bin 디 렉 터 리 에 놓 여 있 습 니 다. AppClassLoader 는 불 러 올 수 있 기 때문에 사용자 정의 로 더 를 호출 하지 않 습 니 다.
시도 방법 1: Animal. class 를 다른 디 렉 터 리, 예 를 들 어 D 디스크 의 루트 디 렉 터 리 에 두 기
Class A can not access a member of class B with modifiers "" 오류.자바 언어 에서 패 킷 접근 멤버 는 컴 파일 할 때 가 아니 라 실행 할 때 패 킷 접근 을 말 합 니 다.따라서 같은 runtime package 에 없 는 구성원 에 게 접근 하려 고 할 때 컴 파일 할 때 같은 가방 에 있 더 라 도 다른 class loader 로 불 러 오 면 자바. lang. IllegalAccessException: Class A can not access a member of class B with modifiers "와 같은 이상 을 얻 을 수 있 습 니 다.
시도 방법 2: 이 Animal. class 의 접 두 사 를 'my Class' 라 고 해서 AppClassLoader 가 찾 을 수 없 도록 합 니 다.
인터넷 에서 해결 할 수 있다 는 사람 이 있 지만 내 실험 결 과 는 방법 1 보 와 같은 이상 이다.
시도 방법 3: 솔 루 션 은 사용자 정의 ClassLoader 를 확장 하여 loadclass 방법 을 다시 쓰 는 것 입 니 다. 현재 클래스 로 더 에서 불 러 온 다음 부모 클래스 로 더 에서 불 러 옵 니 다.
이 해결 방법 은 해결 할 수 있 습 니 다. 인터넷 주 소 는 http://blog.csdn.net/zhangxinrun/article/details/6161426 입 니 다.
참고 블 로그
http://blog.csdn.net/zhangxinrun/article/details/6161426
http://blog.csdn.net/zhouysh/article/details/762300
http://blog.csdn.net/a352193394/article/details/7343385
http://blog.csdn.net/huangbiao86/article/details/6910152
http://www.cnblogs.com/feiling/archive/2012/08/29/2662909.html (암호 화 바이트 코드)

좋은 웹페이지 즐겨찾기