您的位置 首页 java

Java ClassLoader和ClassPath

ClassLoader

Java ClassLoader和ClassPath

Bootstrap ClassLoader

核心类加载器,默认加载路径%JRE_HOME%lib。启动JVM时通过设置-Xbootclasspath可改变加载路径

-Xbootclasspath::完全取代默认的加载路径

-Xbootclasspath/a::拼接到默认的加载路径后面(常用)

-Xbootclasspath/p::拼接到默认的加载路径前面

例如:java -Xbootclasspath/a:”D:Program FilesJavajdk1.8.0_241libtools.jar” -jar xxx.jar

Extention ClassLoader

扩展类加载器,默认加载路径%JRE_HOME%libext。启动JVM时通过设置-Djava.ext.dirs可改变加载路径(覆盖默认的加载路径)

App ClassLoader

应用类加载器,加载classpath下的所有类

自定义类加载

双亲委派机制,也可继承java.net.URLClassLoader

 package com.wyj.agent;

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

public class MyClassLoader extends ClassLoader {
    public String filePath;
    public MyClassLoader(ClassLoader parent, String filePath) {
        super(parent);
        this.filePath = filePath;
    }

    @Override
    public Class findClass(String name) {
        name = name.replaceAll(".", "/");
        byte[] data = loadClassData(name);
        return defineClass(null, data, 0, data.length);
    }

    private byte[] loadClassData(String name) {
        FileInputStream fis = null;
        byte[] data = null;
        try {
            File file = new File(filePath + File.separator + name + ".class");
            System.out.println(file.getAbsolutePath());
            fis = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int ch = 0;
            while ((ch = fis.read()) != -1) {
                baos.write(ch);
            }
            data = baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }
}  

类卸载

  • 类的所有实例已被GC
  • 加载该类的ClassLoader已被GC
  • 该类的Class对象没有在任何地方被引用
  • JVM自带的三种类加载器加载的类不会被卸载

ClassPath

.号代表的是当前目录

缺省值

当前目录

java className

CLASSPATH

系统环境变量,设置后会覆盖缺省值

java className

-classpath

若设置该参数,则会覆盖缺省值以及CLASSPATH

java -classpath “.” className

-jar

CLASSPATH以及-classpath设置无效,只会以启动jar包为搜索范围(这也是为什么应用程序打包成可执行的jar包后,不管你怎么设置classpath都不能引用到第三方jar包的东西了),并且jar包里面的jar也无法被搜索

java -jar xxx.jar

引用第三方jar包的解决方案:

  1. 配置-Xbootclasspath
  2. 把第三方jar包放置到%JRE_HOME%libext目录下或者配置-Djava.ext.dirs
  3. 配置MANIFEST.MF文件中的Class-Path属性来引用第三方jar包
  4. 使用自定义类加载器

Manifest扩展机制

  1. 将第三方jar包copy到启动jar所在的目录或子目录下
  2. 编辑MANIFEST.MF文件中的Class-Path,例如:Class-Path: xxx1.jar lib/xxx2.jar

maven配置Class-Path

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.5</version>
    <configuration>
        <archive>
            <manifest>
                <Main-Class>com.wyj.agent.MyAgent</Main-Class>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>  

文章来源:智云一二三科技

文章标题:Java ClassLoader和ClassPath

文章地址:https://www.zhihuclub.com/187309.shtml

关于作者: 智云科技

热门文章

网站地图