JVM 클래스 로더 분류 및 분석
클래스 로더의 분류
클래스 마운트 가져오기 코드 설명
public class ThreadTest {
public static void main(String[] args) {
// sun.misc.Launcher$AppClassLoader@18b4aac2
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
// sun.misc.Launcher$ExtClassLoader@1540e19d
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);
// null
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(bootstrapClassLoader);
// sun.misc.Launcher$AppClassLoader@18b4aac2
ClassLoader classLoader = ThreadTest.class.getClassLoader();
System.out.println(classLoader);
}
}
클래스 로더 시작(부트 클래스 로더, Bootstra ClassLoader)
확장 클래스 로더(Extension ClassLoader)
클래스 로더에 대한 테스트는 다음과 같습니다.
package com.classload.chapter01;
import sun.misc.Launcher;
import sun.security.ec.CurveDB;
import java.net.URL;
public class ThreadTest {
public static void main(String[] args) {
System.out.println("===== =====");
URL[] urLs = Launcher.getBootstrapClassPath().getURLs();
for (URL url : urLs) {
System.out.println(url);
}
System.out.println("===== =====");
String property = System.getProperty("java.ext.dirs");
for (String path : property.split(";")) {
System.out.println(path);
}
System.out.println("===== =====");
System.out.println(" : CurvDB");
ClassLoader classLoader = CurveDB.class.getClassLoader();
System.out.println(classLoader);
}
}
#
===== =====
file:/D:/JDK/jdk1.8.0_131/jre/lib/resources.jar
file:/D:/JDK/jdk1.8.0_131/jre/lib/rt.jar
file:/D:/JDK/jdk1.8.0_131/jre/lib/sunrsasign.jar
file:/D:/JDK/jdk1.8.0_131/jre/lib/jsse.jar
file:/D:/JDK/jdk1.8.0_131/jre/lib/jce.jar
file:/D:/JDK/jdk1.8.0_131/jre/lib/charsets.jar
file:/D:/JDK/jdk1.8.0_131/jre/lib/jfr.jar
file:/D:/JDK/jdk1.8.0_131/jre/classes
===== =====
D:\JDK\jdk1.8.0_131\jre\lib\ext
C:\Windows\Sun\Java\lib\ext
===== =====
: CurvDB
sun.misc.Launcher$ExtClassLoader@29453f44
상기 코드의 설명: 1. 가이드 클래스 마운트의 스캐닝 디렉터리를 얻을 때
sun.misc.Launcher.getBootstrapClassPath().getURLs();
방법으로 스캐닝한 모든jar 패키지의 디렉터리를 얻을 때2,확장 클래스 마운트의 스캐닝 경로를 얻을 때System.getProperty("java.ext.dirs");
방법은 시스템 속성의java이기 때문이다.tt.dirs에서 클래스 라이브러리 3을 불러오고 클래스를 사용하여 클래스를 테스트합니다. 클래스는classgetClassLoader
방법을 사용합니다.CurvDB는 D:\JDK\jdk1.8.0_131\jre\lib\ext
디렉터리에 있는sunec 패키지의 클래스이기 때문에 클래스를 확장하는 클래스입니다.그런데 만약에 스트링이라는 핵심 가방 밑에 있는 류를 찾는다면?한번 해볼게요.
public static void main(String[] args) {
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1);
}
:null
핵심 패키지는 가이드 클래스 마운트이고, 가이드 클래스 마운트는 C와 C++로 작성되어 있기 때문에 얻을 수 없습니다.
사용자 정의 클래스 로더
사용자 정의 클래스 마운트의 실현 절차: 1. 개발자는 추상적인 클래스java에 따라lang.ClassLoader 클래스의 방식으로 자신의 클래스 마운트를 실현하여 수요를 만족시킵니다.2. JDK에서 1.2 이전에 사용자 정의 클래스 로더를 사용할 때 항상 클래스 로더 클래스를 계승하고 loadClass () 방법을 다시 써서 사용자 정의 클래스 로더를 실현하지만 JDK1.2 이후로loadCass () 방법을 덮어쓰는 것이 아니라 사용자 정의 클래스 불러오기 논리를findClass () 방법에 쓰는 것이 좋습니다.3. 사용자 정의 클래스 로더를 작성할 때 너무 복잡한 수요가 없으면 URLclass Loader 클래스를 직접 계승할 수 있다. 이렇게 하면findClass () 방법을 작성하는 기계가 바이트 코드를 가져오는 방식을 피할 수 있고 사용자 정의 클래스 로더의 작성이 더욱 간결하다.
다음은 코드를 써서 이해해 봅시다.
//CustomClassLoader.java
public class CustomClassLoader extends ClassLoader {
private String path;
/**
* @param path class
*/
public CustomClassLoader(String path) {
this.path = path;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] result = getClassData();
if(result == null) {
throw new FileNotFoundException();
} else {
return defineClass(name, result, 0, result.length);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return super.findClass(name);
}
/**
* @return class
*
*
* byte
*
* path .class
*/
private byte [] getClassData() {
File file = new File(path);
if(file.exists()) {
InputStream in = null;
ByteArrayOutputStream out = null;
try {
in = new FileInputStream(file);
out = new ByteArrayOutputStream();
int length = 0;
byte [] bytes = new byte[1024];
while ((length = in.read(bytes)) != -1) {
out.write(bytes, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return out.toByteArray();
} else {
return null;
}
}
}
테스트 코드:
public class ThreadTest {
public static void main(String[] args) throws ClassNotFoundException {
CustomClassLoader loader = new CustomClassLoader("E:\\IDEA\\JavaBase\\ClassLoad\\target\\classes\\com\\classload\\chapter01\\HelloLoader.class");
Class<?> aClass = loader.loadClass("com.classload.chapter01.HelloLoader");
System.out.println(" :" + aClass.getClassLoader());
Object object = aClass.newInstance();
System.out.println(object);
}
}
# :
:sun.misc.Launcher$AppClassLoader@18b4aac2
execute
com.classload.chapter01.HelloLoader@677327b6
1、우선 클래스의 경로를 사용하여 불러와야 합니다.class 파일,class 파일을 이진 그룹 2로 변환하고 이진 그룹과 파일의 패키지 이름 + 파일 이름에 따라classLoader 클래스의defineClass 방법을 호출하여 클래스의 불러오는 과정을 완성합니다
클래스 불러오기가 완료되면 newInstance () 방법을 사용해서 클래스의 실례를 가져올 수 있으며 getClassLoader () 방법을 사용하면 클래스의 마운트기를 가져올 수 있습니다
자, 클래스의 세 가지 마운트는 여기까지 쓰겠습니다. 끝까지 봐주셔서 감사합니다. 지지해 주셔서 감사합니다.참, 만약 어디에 잘못 썼는지 아래 평론 구역에서 나에게 말해 주세요.886
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.