Java 기초 악 보 -- ClassLoader
참고: http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
--------------------------------------------------------------------------------------------------------------
요점
java.lang.ClassLoader
클래스 의 인 스 턴 스 입 니 다. java.lang.Class
류 의 인 스 턴 스 를 정의 하 는 것 이다.이외에 도 ClassLoader
자바 응용 에 필요 한 자원, 예 를 들 어 이미지 파일 과 프로필 등 을 불 러 오 는 일 도 맡 는 다.방법 설명
getParent()
이 종류의 로 더 의 부모 클래스 로 더 를 되 돌려 줍 니 다.
loadClass(String name)
이름 이
name
인 클래스 를 불 러 옵 니 다. 되 돌아 온 결 과 는 java.lang.Class
클래스 의 인 스 턴 스 입 니 다.findClass(String name)
이름 이
name
인 클래스 를 찾 으 면 java.lang.Class
클래스 의 인 스 턴 스 를 되 돌려 줍 니 다.findLoadedClass(String name)
이름 이
name
인 불 러 온 클래스 를 찾 습 니 다. 되 돌아 온 결 과 는 java.lang.Class
클래스 의 인 스 턴 스 입 니 다.defineClass(String name, byte[] b, int off, int len)
바이트 배열
b
의 내용 을 자바 류 로 바 꾸 고 돌아 온 결 과 는 java.lang.Class
류 의 인 스 턴 스 입 니 다.이 방법 은 final
으로 성명 되 었 다.resolveClass(Class<?> c)
지정 한 자바 클래스 를 연결 합 니 다.
java.lang.ClassLoader
.ClassLoader.getSystemClassLoader()
을 통 해 얻 을 수 있 습 니 다.개발 자 는 계승
java.lang.ClassLoader
류 를 통 해 자신의 클래스 로 더 를 실현 할 수 있다. 클래스 캐리어 트 리 조직 구조 설명 도 는 다음 과 같다. java.lang.Object
클래스 를 인용 해 야 합 니 다. 즉, 실행 할 때 java.lang.Object
클래스 를 JVM 에 불 러 와 야 합 니 다.프 록 시 모드 를 통 해 자바 핵심 라 이브 러 리 의 클래스 에 대한 로 딩 작업 은 유도 류 로 더 에 의 해 통일 적 으로 이 루어 집 니 다. 자바 응용 이 사용 하 는 것 은 모두 같은 버 전의 자바 핵심 라 이브 러 리 클래스 이 고 서로 호 환 되 는 것 을 보장 합 니 다. 서로 다른 클래스 로 더 는 같은 이름 의 클래스 에 추가 이름 공간 을 만 들 었 습 니 다.같은 이름 의 클래스 는 JVM 에 존재 할 수 있 으 며, 다른 클래스 로 불 러 오기 만 하면 됩 니 다.같은 종류의 로 더 를 불 러 오 는 클래스 간 에는 호 환 되 지 않 습 니 다. 이것 은 JVM 내부 에 서로 격 리 된 자바 클래스 공간 을 만 드 는 것 과 같 습 니 다.defineClass
을 통 해 이 루어 진 것 이다.시작 클래스 의 로드 과정 은 호출 loadClass
을 통 해 이 루어 집 니 다.전 자 는 하나의 정의 로 더 (defining loader) 라 고 부 르 고 후 자 는 초기 로 더 (initiating loader) 라 고 부른다.JVM 이 두 클래스 가 같은 지 판단 할 때 클래스 의 정의 로 더 를 사용 합 니 다.즉, 어떤 종류의 로 더 를 시작 하 는 지 는 중요 하지 않 으 며, 중요 한 것 은 이러한 종류의 로 더 를 최종 적 으로 정의 하 는 것 이다.두 종류의 로 더 의 관련 점 은 하나의 정의 로 더 는 다른 종류의 초기 로 더 를 참조 하 는 것 입 니 다.예 를 들 어 클래스 com.example.Outer
는 클래스 com.example.Inner
를 인용 하면 클래스 com.example.Outer
의 정의 로 더 가 시작 클래스 com.example.Inner
의 로드 과정 을 책임 집 니 다.방법 loadClass()
이 던 진 것 은 java.lang.ClassNotFoundException
이상 이다.방법 defineClass()
은 java.lang.NoClassDefFoundError
이상 을 던 졌 다. 클래스 로 더 는 클래스 를 성공 적 으로 불 러 온 후에 얻 은 java.lang.Class
클래스 의 인 스 턴 스 를 캐 시 합 니 다.다음 에 이 종 류 를 불 러 오 라 고 요청 할 때 클래스 로 더 는 캐 시 클래스 의 인 스 턴 스 를 직접 사용 합 니 다. 다시 불 러 오 려 고 하지 않 습 니 다.즉, 하나의 클래스 로 더 인 스 턴 스 에 있어 같은 이름 의 클래스 는 한 번 만 불 러 옵 니 다. 즉, loadClass
방법 은 중복 호출 되 지 않 습 니 다.java.lang.Thread
의 방법 getContextClassLoader()
과 setContextClassLoader(ClassLoader cl)
스 레 드 를 가 져 오고 설정 하 는 컨 텍스트 클래스 로 더 입 니 다.setContextClassLoader(ClassLoader cl)
방법 으로 설정 하지 않 으 면 스 레 드 는 부모 스 레 드 의 컨 텍스트 클래스 로 더 를 계승 합 니 다.자바 가 실행 중인 초기 스 레 드 의 컨 텍스트 클래스 로 더 는 시스템 클래스 로 더 입 니 다.스 레 드 에서 실행 되 는 코드 는 클래스 와 자원 을 불 러 올 수 있 습 니 다.ClassLoader 에 대한 학습 노트
관련 문제
1. Q: 클래스 로 더 를 구현 하 십시오. A: 파일 시스템 클래스 로 더 코드 는 다음 과 같 습 니 다.
package com.example;
public class Sample {
private Sample instance;
public void setSample(Object instance) {
this.instance = (Sample) instance;
}
}
public void testClassIdentity() {
String classDataRootPath = "C:\\workspace\\Classloader\\classData";
FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);
FileSystemClassLoader fscl2 = new FileSystemClassLoader(classDataRootPath);
String className = "com.example.Sample";
try {
Class<?> class1 = fscl1.loadClass(className);
Object obj1 = class1.newInstance();
Class<?> class2 = fscl2.loadClass(className);
Object obj2 = class2.newInstance();
Method setSampleMethod = class1.getMethod("setSample", java.lang.Object.class);
setSampleMethod.invoke(obj1, obj2);
} catch (Exception e) {
e.printStackTrace();
}
}
일반적으로 자신 이 개발 한 클래스 로 더 는 복사
findClass(String name)
방법 만 있 으 면 되 며, 복사 loadClass()
방법 은 없 는 것 이 좋다.2. Q: 다음 코드 를 실행 하면 어떤 상황 이 발생 합 니까?
public class FileSystemClassLoader extends ClassLoader {
private String rootDir;
public FileSystemClassLoader(String rootDir) {
this.rootDir = rootDir;
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = getClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
}
else {
return defineClass(name, classData, 0, classData.length);
}
}
private byte[] getClassData(String className) {
String path = classNameToPath(className);
try {
InputStream ins = new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesNumRead = 0;
while ((bytesNumRead = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesNumRead);
}
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String classNameToPath(String className) {
return rootDir + File.separatorChar
+ className.replace('.', File.separatorChar) + ".class";
}
}
A: 운행 시 이상
java.lang.ClassCastException
을 던 집 니 다.두 대상 obj1
과 obj2
의 클래스 이름 은 같 지만, 이 두 종 류 는 서로 다른 클래스 의 인 스 턴 스 로 불 러 오기 때문에 JVM 에 의 해 동일 하 다 고 여 겨 지지 않 는 다.JVM 은 두 자바 류 가 같은 지 어떻게 판단 합 니까? 클래스 의 전체 이름 이 같은 지 뿐만 아니 라 이러한 종류의 로 더 를 불 러 오 는 것 이 같은 지, 둘 다 같은 경우 에 만 두 가지 유형 이 같다 고 생각 합 니 다.같은 바이트 코드 라 도 서로 다른 종류의 로 더 에 불 러 온 후에 얻 은 클래스 는 다르다.
3. Q: 사용자 정의 클래스 로 더 의 응용 장 소 를 말씀 해 주 시 겠 습 니까?
A: 1) 자바 바이트 코드 (. class 파일) 를 서버 에 저장 하고 클 라 이언 트 는 네트워크 를 통 해 바이트 코드 를 가 져 와 실행 합 니 다.버 전이 업데이트 되 었 을 때 서버 에 저 장 된 파일 만 교체 하면 됩 니 다.
2) 응용 프로그램 은 네트워크 를 통 해 자바 류 의 바이트 코드 를 전송 하고 안전성 을 확보 하기 위해 이 바이트 코드 들 은 암호 화 처 리 를 거 쳤 다.이 럴 때 암호 화 된 바이트 코드 를 네트워크 주소 에서 읽 고 복호화 와 검증 을 한 다음 JVM 에서 실행 할 클래스 를 정의 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.