0
点赞
收藏
分享

微信扫一扫

JVM核心之JVM运行和类加载全过程

JVM核心之JVM运行和类加载全过程_class
JVM核心之JVM运行和类加载全过程_class文件的加载_02
JVM核心之JVM运行和类加载全过程_class文件的加载_03
JVM核心之JVM运行和类加载全过程_class文件的加载_04
JVM核心之JVM运行和类加载全过程_加载_05

package JVMLoad;

public class Demo01 {

static{
System.out.println("Demo01类的静态初始化");
}

public static void main(String[] args) throws Exception{

System.out.println("Demo01的main方法");

// 主动引用
// new A();
// System.out.println(A.width);
// Class.forName("JVMLoad.A");

// 被动引用,不会发生类的初始化
// System.out.println(A.MAX);
// A[] as = new A[10];
System.out.println(B.width); // 通过子类的对象调用父类的静态变量时,子类不会被初始化
}

}

class B extends A{
static {
System.out.println("B类的静态初始化");
}
}

class A extends A_Father{
public static int width = 100;
public static final int MAX = 123;

static {
System.out.println("A类的静态初始化");
}

public A(){
System.out.println("A类的构造方法初始化");
}

}

class A_Father{
static {
System.out.println("A_Father类的静态初始化...");
}
}

​主动引用​

JVM核心之JVM运行和类加载全过程_class文件的加载_06

​被动引用​

JVM核心之JVM运行和类加载全过程_jvm_07
​​​被动引用之通过子类对象调用父类静态变量(B extends A)​​​JVM核心之JVM运行和类加载全过程_jvm_08
JVM核心之JVM运行和类加载全过程_java_09
JVM核心之JVM运行和类加载全过程_加载_10

JVM核心之JVM运行和类加载全过程_加载_11
JVM核心之JVM运行和类加载全过程_class文件的加载_12

package JVMLoad;

public class Demo02 {

public static void main(String[] args) {

System.out.println(ClassLoader.getSystemClassLoader());
System.out.println(ClassLoader.getSystemClassLoader().getParent());
System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());

System.out.println(System.getProperty("java.class.path"));
}
}

​Idea运行​​​JVM核心之JVM运行和类加载全过程_加载_13

JVM核心之JVM运行和类加载全过程_java_14

自定义加载器

JVM核心之JVM运行和类加载全过程_class文件的加载_15

命令行编译带包的java原文件

JVM核心之JVM运行和类加载全过程_java_16
JVM核心之JVM运行和类加载全过程_java_17
​​​FileSystemClassLoader​

package JVMLoad;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* 自定义文件系统类加载器
*/
public class FileSystemClassLoader extends ClassLoader{

private String rootDir;

public FileSystemClassLoader(String rootDir){
this.rootDir = rootDir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);

// 先查询有没有加载过这个类.如果已经加载,则直接返回加载好的类.如果没有,则加载
if (c!=null){
return c;
}else {

ClassLoader parent = this.getParent();

try {
c = parent.loadClass(name); // 委派给父类加载
}catch (Exception e){

}

if (c!=null){
return c;
}else {
// 将指定的class文件转换成byte数组
byte[] classData = getClassData(name);
if (classData == null){
throw new ClassNotFoundException();
}else {

c = defineClass(name, classData, 0, classData.length);
}
}
}

return c;

}

private byte[] getClassData(String classname){
String path = rootDir + "/" + classname.replace(".", "/") + ".class";

InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
is = new FileInputStream(path);

byte[] buffer = new byte[1024];
int temp = 0;
while ((temp=is.read(buffer))!=-1){
baos.write(buffer, 0, temp);
}

return baos.toByteArray();

} catch (IOException e) {
e.printStackTrace();
return null;
}finally {
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}

if (baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

​Demo03​

package JVMLoad;

/**
* 测试自定义的FileSystemClassLoader
*/

public class Demo03 {

public static void main(String[] args) throws Exception{

FileSystemClassLoader loader = new FileSystemClassLoader("/home/sweetheart");
FileSystemClassLoader loader2 = new FileSystemClassLoader("/home/sweetheart");

Class<?> c1 = loader.loadClass("JVMLoad.Test");
Class<?> c2 = loader.loadClass("JVMLoad.Test");
Class<?> c3 = loader2.loadClass("JVMLoad.Test");

Class<?> c4 = loader2.loadClass("java.lang.String");
Class<?> c5 = loader2.loadClass("JVMLoad.Demo01");

System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode()); // 用一个类,被不同的加载器加载,JVM认为也是不相同的类

System.out.println(c3.getClassLoader()); // 自定义加载器
System.out.println(c4.getClassLoader()); // 引导类加载器
System.out.println(c5.getClassLoader()); // 系统默认的类加载器
}
}

JVM核心之JVM运行和类加载全过程_java_18
​​​网络类加载器​

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
* 网络类加载器
*/
public class NetClassLoader extends ClassLoader{

private String rootUrl;

public NetClassLoader(String rootDir){
this.rootUrl = rootDir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);

// 先查询有没有加载过这个类.如果已经加载,则直接返回加载好的类.如果没有,则加载
if (c!=null){
return c;
}else {

ClassLoader parent = this.getParent();

try {
c = parent.loadClass(name); // 委派给父类加载
}catch (Exception e){

}

if (c!=null){
return c;
}else {
// 将指定的class文件转换成byte数组
byte[] classData = getClassData(name);
if (classData == null){
throw new ClassNotFoundException();
}else {

c = defineClass(name, classData, 0, classData.length);
}
}
}

return c;

}

private byte[] getClassData(String classname){
String path = rootUrl + "/" + classname.replace(".", "/") + ".class";

InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
URL url = new URL(path);
is = url.openStream();

byte[] buffer = new byte[1024];
int temp = 0;
while ((temp=is.read(buffer))!=-1){
baos.write(buffer, 0, temp);
}

return baos.toByteArray();

} catch (IOException e) {
e.printStackTrace();
return null;
}finally {
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}

if (baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

​加密解密类加载器​

​加密工具类​

package JVMLoad;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
* 加密工具类
*/
public class EncrptUtil {

public static void encrpt(String src, String dest){

FileInputStream fis = null;
FileOutputStream fos = null;

try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dest);

int temp = -1;
while ((temp=fis.read())!=-1){
fos.write(temp^0xff); // 取反操作
}


}catch (IOException e){
e.printStackTrace();
}finally {
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}

if (fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

​加载文件系统中加密后的class字节码的类加载器​

package JVMLoad;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* 加载文件系统中加密后的class字节码的类加载器
*/
public class DecrptClassLoader extends ClassLoader{

private String rootDir;

public DecrptClassLoader(String rootDir){
this.rootDir = rootDir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);

// 先查询有没有加载过这个类.如果已经加载,则直接返回加载好的类.如果没有,则加载
if (c!=null){
return c;
}else {

ClassLoader parent = this.getParent();

try {
c = parent.loadClass(name); // 委派给父类加载
}catch (Exception e){

}

if (c!=null){
return c;
}else {
// 将指定的class文件转换成byte数组
byte[] classData = getClassData(name);
if (classData == null){
throw new ClassNotFoundException();
}else {

c = defineClass(name, classData, 0, classData.length);
}
}
}

return c;

}

private byte[] getClassData(String classname){
String path = rootDir + "/" + classname.replace(".", "/") + ".class";

InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
is = new FileInputStream(path);

int temp = -1;
while ((temp=is.read())!=-1){
baos.write(temp^0xff); // 取反操作
}
return baos.toByteArray();

} catch (IOException e) {
e.printStackTrace();
return null;
}finally {
if (is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}

if (baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

​Demo04​

package JVMLoad;

/**
* 测试简单加密解密(取反操作)
*/
public class Demo04 {

public static void main(String[] args) throws Exception{
int a = 3; // 00000011
System.out.println(Integer.toBinaryString(a^0xff));

// EncrptUtil.encrpt("/home/sweetheart/JVMLoad/Test.class", "./src/JVMLoad/Test.class");

// FileSystemClassLoader loader = new FileSystemClassLoader("./src");
//
// Class<?> c = loader.loadClass("JVMLoad.Test");
// System.out.println(c);

DecrptClassLoader loader = new DecrptClassLoader("./src");

Class<?> c = loader.loadClass("JVMLoad.Test");
System.out.println(c);

}
}

JVM核心之JVM运行和类加载全过程_class文件的加载_19

​当用之前普通的类加载器加载时,出现ClassFormatError错误​​​JVM核心之JVM运行和类加载全过程_java_20
​利用对应的解密类加载器​

JVM核心之JVM运行和类加载全过程_jvm_21

线程上下文类加载器

JVM核心之JVM运行和类加载全过程_加载_22

package JVMLoad;

public class Demo05 {

public static void main(String[] args) throws Exception{

ClassLoader loader = Demo05.class.getClassLoader();
System.out.println(loader);

ClassLoader loader2 = Thread.currentThread().getContextClassLoader();
System.out.println(loader2);

Thread.currentThread().setContextClassLoader(new FileSystemClassLoader("./"));
System.out.println(Thread.currentThread().getContextClassLoader());

Class<Demo01> c = (Class<Demo01>) Thread.currentThread().getContextClassLoader().loadClass("JVMLoad.Demo01");
System.out.println(c);
System.out.println(c.getClassLoader());
}
}

JVM核心之JVM运行和类加载全过程_class文件的加载_23

Tomcat服务器的类加载机制

JVM核心之JVM运行和类加载全过程_class_24

OSGI

JVM核心之JVM运行和类加载全过程_java_25
JVM核心之JVM运行和类加载全过程_class_26


举报

相关推荐

0 条评论