javaextdir的简单介绍

博主:adminadmin 2022-11-26 14:01:08 71

本篇文章给大家谈谈javaextdir,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

java -Djava.ext.dirs=lib/ com.jar

与这个批处理命令文件同级目录下的一个lib文件夹下面;

举个例子,D:/test,(D盘下面有个test文件夹)test下面有一个文件test.bat和一个文件夹lib;

这样 test.bat里面内容就是 java -Djava.ext.dirs=lib.......这一串命令。这里面写的lib 就是指的d盘test文件夹下的lib目录。

classpath 和 java.ext.dirs 的区别

spring可以通过指定classpath*:与classpath:前缀加路径的方式从classpath加载文件,如bean的定义文件.classpath*:的出现是为了从多个jar文件中加载相同的文件.classpath:只能加载找到的第一个文件. 比如 resource1.jar中的package 'com.test.rs

java 中System.getProperty( dic.dir ) 是什么意思

java可以通过System.getProperty获得系统变量的值。而java.library.path只是其中的一个,表示系统搜索库文件的路径。

例如这个值可以能是 c;\windows;d:\test;e:\mytest

那当你在程序中装载一个dll库时,系统就是去当前目录和这几个目录找看看有没有这个文件。

这个类作用是很大的,我们可以获取很多信息。

System.getProperty()参数大全

java.version Java Runtime Environment version

java.vendor Java Runtime Environment vendor

java.vendor.url Java vendor URL

java.home Java installation directory

java.vm.specification.version Java Virtual Machine specification version

java.vm.specification.vendor Java Virtual Machine specification vendor

java.vm.specification.name Java Virtual Machine specification name

java.vm.version Java Virtual Machine implementation version

java.vm.vendor Java Virtual Machine implementation vendor

java.vm.name Java Virtual Machine implementation name

java.specification.version Java Runtime Environment specification version

java.specification.vendor Java Runtime Environment specification vendor

java.specification.name Java Runtime Environment specification name

java.class.version Java class format version number

java.class.path Java class path

java.library.path List of paths to search when loading libraries

java.io.tmpdir Default temp file path

java.compiler Name of JIT compiler to use

java.ext.dirs Path of extension directory or directories

os.name Operating system name

os.arch Operating system architecture

os.version Operating system version

file.separator File separator ("/" on UNIX)

path.separator Path separator (":" on UNIX)

line.separator Line separator ("\n" on UNIX)

user.name User's account name

user.home User's home directory

user.dir User's current working directory

Java获取当前路径的几种方法

1、利用System.getProperty()函数获取当前路径:

System.out.println(System.getProperty("user.dir"));//user.dir指定了当前的路径

2、使用File提供的函数获取当前路径:

File directory = new File("");//设定为当前文件夹

try{

System.out.println(directory.getCanonicalPath());//获取标准的路径

System.out.println(directory.getAbsolutePath());//获取绝对路径

}catch(Exceptin e){}

File.getCanonicalPath()和File.getAbsolutePath()大约只是对于new File(".")和new File("..")两种路径有所区别。

# 对于getCanonicalPath()函数,“."就表示当前的文件夹,而”..“则表示当前文件夹的上一级文件夹

# 对于getAbsolutePath()函数,则不管”.”、“..”,返回当前的路径加上你在new File()时设定的路径

# 至于getPath()函数,得到的只是你在new File()时设定的路径

比如当前的路径为 C:/test :

File directory = new File("abc");

directory.getCanonicalPath(); //得到的是C:/test/abc

directory.getAbsolutePath(); //得到的是C:/test/abc

direcotry.getPath(); //得到的是abc

File directory = new File(".");

directory.getCanonicalPath(); //得到的是C:/test

directory.getAbsolutePath(); //得到的是C:/test/.

direcotry.getPath(); //得到的是.

File directory = new File("..");

directory.getCanonicalPath(); //得到的是C:/

directory.getAbsolutePath(); //得到的是C:/test/..

direcotry.getPath(); //得到的是..

另外:System.getProperty()中的字符串参数如下:

System.getProperty()参数大全

# java.version Java Runtime Environment version

# java.vendor Java Runtime Environment vendor

# java.vendor.url Java vendor URL

# java.home Java installation directory

# java.vm.specification.version Java Virtual Machine specification version

# java.vm.specification.vendor Java Virtual Machine specification vendor

# java.vm.specification.name Java Virtual Machine specification name

# java.vm.version Java Virtual Machine implementation version

# java.vm.vendor Java Virtual Machine implementation vendor

# java.vm.name Java Virtual Machine implementation name

# java.specification.version Java Runtime Environment specification version

# java.specification.vendor Java Runtime Environment specification vendor

# java.specification.name Java Runtime Environment specification name

# java.class.version Java class format version number

# java.class.path Java class path

# java.library.path List of paths to search when loading libraries

# java.io.tmpdir Default temp file path

# java.compiler Name of JIT compiler to use

# java.ext.dirs Path of extension directory or directories

# os.name Operating system name

# os.arch Operating system architecture

# os.version Operating system version

# file.separator File separator ("/" on UNIX)

# path.separator Path separator (":" on UNIX)

# line.separator Line separator ("/n" on UNIX)

# user.name User’s account name

# user.home User’s home directory

# user.dir User’s current working directory

JAVA中获取路径:

1.jsp中取得路径:

以工程名为TEST为例:

(1)得到包含工程名的当前页面全路径:request.getRequestURI()

结果:/TEST/test.jsp

(2)得到工程名:request.getContextPath()

结果:/TEST

(3)得到当前页面所在目录下全名称:request.getServletPath()

结果:如果页面在jsp目录下 /TEST/jsp/test.jsp

(4)得到页面所在服务器的全路径:application.getRealPath("页面.jsp")

结果:D:/resin/webapps/TEST/test.jsp

(5)得到页面所在服务器的绝对路径:absPath=new java.io.File(application.getRealPath(request.getRequestURI())).getParent();

结果:D:/resin/webapps/TEST

2.在类中取得路径:

(1)类的绝对路径:Class.class.getClass().getResource("/").getPath()

结果:/D:/TEST/WebRoot/WEB-INF/classes/pack/

(2)得到工程的路径:System.getProperty("user.dir")

结果:D:/TEST

3.在Servlet中取得路径:

(1)得到工程目录:request.getSession().getServletContext().getRealPath("") 参数可具体到包名。

结果:E:/Tomcat/webapps/TEST

(2)得到IE地址栏地址:request.getRequestURL()

结果:

(3)得到相对地址:request.getRequestURI()

结果:/TEST/test

如何用JAVA实现根据文件后缀名分类文件,并且将文件复制到不同的文件夹

处理的代码逻辑如下:

public static void main(String args[]) {

String saveToFileDir = "F:\\整理后的文件存放目录";

File file = new File("F:\\所需整理的文件目录");

processFileFenLei(saveToFileDir, file);

}

private static void processFileFenLei(String saveToFileDir, File file) {

if (file.getName().startsWith(".")) {

return;

}

System.out.println("当前处理位置===" + file.getAbsolutePath());

if (file.isFile()) {

processCopyFile(saveToFileDir, file);

} else {

File[] subFiles = file.listFiles();

for (File subFile : subFiles) {

processFileFenLei(saveToFileDir, subFile);

}

}

}

private static void processCopyFile(String saveToFileDir, File file) {

String extFileName = FileCreateUtil.getFileExtension(file);

String wholeDir = saveToFileDir + "\\" + extFileName;

File fileDir = new File(wholeDir);

if (!fileDir.exists()) {

fileDir.mkdirs();

}

File saveToFile = new File(wholeDir + "\\" + file.getName());

FileCreateUtil.saveFileToFile(file, saveToFile);

}

以上代码中所用到的文件操作工具类:

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.sql.Blob;

import java.sql.SQLException;

/**

 * @作者 王建明

 * @创建日期 Feb 4, 2010

 * @创建时间 9:56:15 AM

 * @版本号 V 1.0

 */

public class FileCreateUtil {

private static final String CONTENT_TYPE_IMAGE = "image/jpeg";

/**

 * @说明 将二进制字节流保存为文件

 * @param byteArry二进制流

 * @param file要保存的文件

 * @throws SQLException

 * @throws IOException

 */

public static void saveByteArry2File(byte[] byteArry, File file)

throws SQLException, IOException {

BufferedOutputStream bos = new BufferedOutputStream(

new FileOutputStream(file));

bos.write(byteArry);

bos.close();

}

/**

 * @说明 将文件转换为二进制字节流

 * @param file要转换的文件

 * @return

 * @throws SQLException

 * @throws IOException

 */

public static byte[] changeFile2Bytes(File file) throws SQLException,

IOException {

long len = file.length();

byte[] bytes = new byte[(int) len];

FileInputStream inputStream = new FileInputStream(file);

BufferedInputStream bufferedInputStream = new BufferedInputStream(

inputStream);

int r = bufferedInputStream.read(bytes);

if (r != len) {

throw new IOException("File read error");

}

inputStream.close();

bufferedInputStream.close();

return bytes;

}

/**

 * @说明 将Blob类类型的文件转换成二进制字节流

 * @param pic

 * @return

 * @throws SQLException

 * @throws IOException

 */

public static byte[] changeBlob2Bytes(Blob pic) throws SQLException,

IOException {

byte[] bytes = pic.getBytes(1, (int) pic.length());

return bytes;

}

/**

 * @说明 将Blob类类型的数据保存为本地文件

 * @param blob

 * @param file

 * @throws SQLException

 * @throws IOException

 */

public static void saveBlob2File(Blob blob, File file) throws SQLException,

IOException {

InputStream is = blob.getBinaryStream();

BufferedOutputStream bos = new BufferedOutputStream(

new FileOutputStream(file));

int b = -1;

while ((b = is.read()) != -1) {

bos.write(b);

}

bos.close();

is.close();

}

/**

 * @说明 将一个文件拷贝到另一个文件中

 * @param oldFile源文件

 * @param newFile目标文件

 */

public static void saveFileToFile(File oldFile, File newFile) {

FileInputStream fis = null;

FileOutputStream fos = null;

try {

fis = new FileInputStream(oldFile); // 建立文件输入流

fos = new FileOutputStream(newFile);

int r;

while ((r = fis.read()) != -1) {

fos.write((byte) r);

}

} catch (FileNotFoundException ex) {

System.out.println("Source File not found");

} catch (IOException ex) {

System.out.println(ex.getMessage());

} finally {

try {

if (fis != null)

fis.close();

if (fos != null)

fos.close();

} catch (IOException ex) {

System.out.println(ex);

}

}

}

/**

 * @说明 获取文本形式文件的内容

 * @param file要读取的文件

 * @return

 */

public static String getTxtFileContent(File file) {

BufferedReader br = null;

try {

br = new BufferedReader(new FileReader(file));

String line = null;

StringBuilder sb = new StringBuilder((int) file.length());

while ((line = br.readLine()) != null) {

sb.append(line);

sb.append("\n");

}

return sb.toString();

} catch (FileNotFoundException e) {

e.printStackTrace();

System.out.println("File not found");

} catch (IOException e) {

e.printStackTrace();

System.out.println("Read file error");

} finally {

try {

if (br != null)

br.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return "";

}

/**

 * @说明 把一个文件转化为字节

 * @param file

 * @return byte[]

 * @throws Exception

 */

public static byte[] getByteFromFile(File file) throws Exception {

byte[] bytes = null;

if (file != null) {

InputStream is = new FileInputStream(file);

int length = (int) file.length();

if (length  Integer.MAX_VALUE) // 当文件的长度超过了int的最大值

{

System.out.println("this file is max ");

return null;

}

bytes = new byte[length];

int offset = 0;

int numRead = 0;

while (offset  bytes.length

 (numRead = is.read(bytes, offset, bytes.length - offset)) = 0) {

offset += numRead;

}

// 如果得到的字节长度和file实际的长度不一致就可能出错了

if (offset  bytes.length) {

System.out.println("file length is error");

return null;

}

is.close();

}

return bytes;

}

/**

 * @说明 将指定文本内容写入到指定文件中(原文件将被覆盖!)

 * @param content要写入的内容

 * @param file写到的文件

 */

public static void writeContentIntoFile(String content, File file) {

try {

if (file.exists()) {

file.delete();

}

file.createNewFile();

FileWriter fw = new FileWriter(file, true);

BufferedWriter bw = new BufferedWriter(fw);

bw.write(content);

bw.close();

fw.close();

} catch (IOException e) {

System.out.println("Write file error");

e.printStackTrace();

}

}

/**

 * @param file

 * @param encode

 * @return

 * @throws Exception

 *             T:2012-03-01 11:12:51 A:王建明 X:问题ID—— R:备注——读取文件时设置txt文件的编码方式

 */

public static String readFileContent(File file, String encode)

throws Exception {

StringBuilder sb = new StringBuilder();

if (file.isFile()  file.exists()) {

InputStreamReader insReader = new InputStreamReader(

new FileInputStream(file), encode);

BufferedReader bufReader = new BufferedReader(insReader);

String line = new String();

while ((line = bufReader.readLine()) != null) {

// System.out.println(line);

sb.append(line + "\n");

}

bufReader.close();

insReader.close();

}

return sb.toString();

}

/**

 * @param file

 * @return T:2012-03-01 11:12:25 A:王建明 X:问题ID—— R:备注——获取txt文件的编码格式

 */

public static String getTxtEncode(File file) {

String code = "";

try {

InputStream inputStream = new FileInputStream(file);

byte[] head = new byte[3];

inputStream.read(head);

code = "gb2312";

if (head[0] == -1  head[1] == -2)

code = "UTF-16";

if (head[0] == -2  head[1] == -1)

code = "Unicode";

if ((head[0] == -17  head[1] == -69  head[2] == -65))

code = "UTF-8";

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return code;

}

/**

 * @说明 获取文件后缀名

 * @param file

 * @return

 */

public static String getFileExtension(File file) {

if (file != null  file.isFile()) {

String filename = file.getName();

int i = filename.lastIndexOf(".");

if (i  0  i  filename.length() - 1) {

return filename.substring(i + 1).toLowerCase();

}

}

return "";

}

/**

 * @说明 删除文件或文件夹

 * @param file

 * @作者 王建明

 * @创建日期 2012-5-26

 * @创建时间 上午09:36:58

 * @描述 ——

 */

public static void deleteFile(File file) {

if (file.exists()) { // 判断文件是否存在

if (file.isFile()) { // 判断是否是文件

file.delete(); // delete()方法 你应该知道 是删除的意思;

} else if (file.isDirectory()) { // 否则如果它是一个目录

File files[] = file.listFiles(); // 声明目录下所有的文件 files[];

for (int i = 0; i  files.length; i++) { // 遍历目录下所有的文件

deleteFile(files[i]); // 把每个文件 用这个方法进行迭代

}

}

file.delete();

} else {

System.out.println("所删除的文件不存在!" + '\n');

}

}

/**

 * @说明 创建文件夹,如果不存在的话

 * @param dirPath

 * @作者 王建明

 * @创建日期 2012-5-26

 * @创建时间 上午09:49:12

 * @描述 ——

 */

public static void createMirs(String dirPath) {

File dirPathFile = new File(dirPath);

if (!dirPathFile.exists())

dirPathFile.mkdirs();

}

}

java解释器如何加载类?

类加载次序:1、静态代码块或者静态方法-2、main方法调用到的方法

对象加载次序:1、静态代码块或者静态方法-2、非静态代码块或者非静态方法-3、对象的构造方法。

但是有一段代码没有办法解释。代码忘了,过段时间丢上来

个人感觉应该好像不大对劲,我觉得应该是:

类装载时,1、静态代码块或者静态方法被调用

然后是程序的运行,main调用到的方法会被执行,如果是新建一个对象,则

2、非静态代码块或者非静态方法-3、对象的构造方法顺序执行。

===============================================

首先我们要分析类加载原理,java中默认有三种类加载器:引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)引导类加载器负责加载jdk中的系统类,这种类加载器都是用c语言实现的,在java程序中没有办法获得这个类加载器,对于java程序是一个概念而已,基本上不用考虑它的存在,像String,Integer这样的类都是由引导类加载器加载器的.

扩展类加载器负责加载标准扩展类,一般使用java实现,这是一个真正的java类加载器,负责加载jre/lib/ext中的类,和普通的类加载器一样,其实这个类加载器对我们来说也不是很重要,我们可以通过java程序获得这个类加载器。

系统类加载器,加载第一个应用类的加载器(其实这个定义并不准确,下面你将会看到),也就是执行java MainClass 时加载MainClass的加载器,这个加载器使用java实现,使用的很广泛,负责加载classpath中指定的类。

类加载器之间有一定的关系(父子关系),我们可以认为扩展类加载器的父加载器是引导类加载器(当然不这样认为也是可以的,因为引导类加载器表现在java中就是一个null),不过系统类加载器的父加载器一定是扩展类加载器,类加载器在加载类的时候会先给父加载器一个机会,只有父加载器无法加载时才会自己去加载。

我们无法获得引导类加载器,因为它是使用c实现的,而且使用引导类加载器加载的类通过getClassLoader方法返回的是null.所以无法直接操作引导类加载器,但是我们可以根据Class.getClassLoader方法是否为null判断这个类是不是引导类加载器加载的,可以通过下面的方法获得引导类加载器加载的类路径(每个jar包或者文件夹对应了一个URL);

sun.misc.Launcher.getBootstrapClassPath().getURLs()

你可以直接在你的main函数中输出就可以了

System.out.println(java.util.Arrays.asList(sun.misc.Launcher.getBootstrapClassPath().getURLs()).toString());

得到的结果是:

[file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/rt.jar,

file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/i18n.jar,

file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/sunrsasign.jar,

file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/jsse.jar,

file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/jce.jar,

file:/C:/Program%20Files/Java/j2re1.4.2_10/lib/charsets.jar,

file:/C:/Program%20Files/Java/j2re1.4.2_10/classes]

其实我们是可以指定引导类加载器的类路径的,java提供了一个-Xbootclasspath参数,不过这个参数不是标准参数。

java -Xbootclasspath: 运行时指定引导类加载器的加载路径(jar文件或者目录)

java -Xbootclasspath/p:和上面的相同,不过把这个路径放到原来的路径前面

java -Xbootclasspath/a:这个就是在原引导类路径后面添加类路径。

上面我们有提过加载第一个应用类未必就是系统加载器。

如果我把这个应用类的路径放到引导类路径中,它将会被引导类加载器加载,大致这样

java -Xbootclasspath/a:myjar.jar MainClass

如果MainClass在myjar.jar中,那么这个类将会被引导类加载器加载。

如果希望看详情,使用-verbose参数,为了看的更清楚,使用重定向,大致为(windows下):

java -verbose -Xbootclasspath/a:myjar.jar MainClass - C:\out.txt

通过这个参数我们可以实现自己的系统类,比如替换掉java.lang.Object的实现,自己可以扩展

一些方法,不过这样做似乎没有好处,因为那就不是标准了。

我们最关心的还是系统类加载器,一般都认为系统类加载器是加载应用程序第一个类的加载器,

也就是java MainClass命令中加载MainClass的类加载器,这种说法虽然不是很严谨,但基本上还是可以这样认为的,因为我们很少会改变引导类加载器和扩展类加载器的默认行为。应该说系统类加载器负责加载classpath路径中的而且没有被扩展类加载器加载的类(当然也包括引导类加载器加载的)。如果classpath中有这个类,但是这个类也在扩展类加载器的类路径,那么系统类加载器将没有机会加载它。

我们很少改变扩展类加载器的行为,所以一般你自己定义的类都是系统类加载器加载器的。

获得系统类加载器非常简单,假设MyClass是你定义的一个类

MyClass.class.getClassLoader()返回的就是系统类加载器,当然这种方法无法保证绝对正确,我们可以使用更简单而且一定正确的方式:

ClassLoader.getSystemClassLoader()获得系统类加载器。我们知道ClassLoader是一个抽象类,所以系统类加载器肯定是ClassLoader的一个子类实现。我们来看看它是什么

ClassLoader.getSystemClassLoader().getClass();

结果是class sun.misc.Lancher$AppClassLoader

可以看出这是sun的一个实现,从名字可以看出是一个内部类,目前我也没有看到这个源代码,似乎还不是很清晰:

我们在看看它的父类是什么:

ClassLoader.getSystemClassLoader().getClass().getSuperclass();

结果是:class java.net.URLClassLoader

这个是j2se的标准类,它的父类是SecureClassLoader,而SecureClassLoader是继承ClassLoader的。

现在整个关系应该很清楚,我们会看到几乎所有的ClassLoader实现都是继承URLClassLoader的。

因为系统类加载器是非常重要的,而且是我们可以直接控制的,所以我们后面还会介绍,不过先来看一下扩展类

加载器以及它们之间的关系。

扩展类加载器似乎是一个不起眼的角色,它负责加载java的标准扩展(jre/lib/ext目录下的所有jar),它其实就是一个普通的加载器,看得见摸得着的。

首先的问题是怎么知道扩展类加载器在哪里?

的确没有直接途径获得扩展类加载器,但是我们知道它是系统类加载器的父加载器,我们已经很容易的获得系统类加载器了,所以我们可以间接的获得扩展类加载器:

ClassLoader.getSystemClassLoader().getParent().getClass();

其实是通过系统类加载器间接的获得了扩展类加载器,看看是什么东西:

结果是:class sun.misc.Launcher$ExtClassLoader

这个类和系统类加载器一样是一个内部类,而且定义在同一个类中。

同样看看它的父类是什么:

ClassLoader.getSystemClassLoader().getParent().getClass().getSuperclass();

可以看出结果也是class java.net.URLClassLoader

扩展类加载jre/lib/ext目录下的所有类,包括jar,目录下的所有类(目录名不一定要classes).

现在可以回答上面的问题了,你写一个HelloWorld,放到jre/lib/ext/下的某个目录

比如 jre/lib/ext/myclass/HelloWorld.class

然后在你classpath也设置一份到这个类的路径,结果执行java HelloWorld时,这个类是被扩展类加载器加载器的,可以这样证明

public static void main(String[] args){

System.out.println("loaded by"+HelloWorld.class.getClassLoader().getClass());

System.out.println("Hello World");

}

结果可以得到class sun.misc.Launcher$ExtClassLoader

当然如果你把jre/lib/ext下myclass这个目录删除,仍然可以运行,但是这样结果是

class sun.misc.Lancher$AppClassLoader

如果你不知道这个过程的话,假设在你扩展类路径下有一份classpath中的拷贝,或者是比较低的版本,当你使用新的版本时会发现没有起作用,知道这个过程你就不会觉得奇怪了。另外就是两个不同的类加载器是可以加载一个同名的类的,也就是说虽然扩展类加载器加载了某个类,系统类加载器是可以加载自己的版本的,

但是现有的实现都没有这样做,ClassLoader中的方法是会请求父类加载器先加载的,如果你自己定义类加载器完全可以修改这种默认行为,甚至可以让他没有父加载器。

这里给出一个方法如何获得扩展类加载器加载的路径:

String path=System.getProperty("java.ext.dirs");

File dir=new File(path);

if(!dir.exists()||!dir.isDirectory()){

return Collections.EMPTY_LIST;

}

File[] jars=dir.listFiles();

URL[] urls=new URL[jars.length];

for(int i=0;ijars.length;i++){

urls[i]=sun.misc.URLClassPath.pathToURLs(jars[i].getAbsolutePath())[0];

}

return Arrays.asList(urls);

对于扩展类加载器我们基本上不会去关心,也很少把你自己的jar放到扩展路径,大部分情况下我们都感觉不到它的存在,当然如果你一定要放到这个目录下,一定要知道这个过程,它会优先于classpath中的类。

现在我们应该很清楚知道某个类是哪个加载器加载的,并且知道为什么是它加载的,如果要在运行时获得某个类的类加载器,直接使用Class的getClassLoader()方法就可以了。

用户定义的类一般都是系统类加载器加载的,我们很少直接使用类加载器加载类,我们甚至很少自己加载类。

因为类在使用时会被自动加载,我们用到某个类时该类会被自动加载,比如new A()会导致类A自动被加载,不过这种加载只发生一次。

我们也可以使用系统类加载器手动加载类,ClassLoader提供了这个接口

ClassLoader.getSystemClassLoader().loadClass("classFullName");

这就很明确的指定了使用系统类加载器加载指定的类,但是如果该类能够被扩展类加载器加载,系统类加载器还是不会有机会的。

我们最常用的还是使用Class.forName加载使用的类,这种方式没有指定某个特定的ClassLoader,会使用调用类的ClassLoader。

也就是说调用这个方法的类的类加载器将会用于加载这个类。比如在类A中使用Class.forName加载类B,那么加载类A的类加载器将会用于加载类B,这样两个类的类加载器是同一个。

最后讨论一下如何获得某个类加载器加载了哪些类,这个似乎有一定的使用价值,可以看出哪些类被加载了。其实这个也不是很难,因为ClassLoader中有一个classes成员变量就是用来保存类加载器加载的类列表,而且有一个方法

void addClass(Class c) { classes.addElement(c);}

这个方法被JVM调用。

我们只要利用反射获得classes这个值就可以了,不过classes声明为private的,我们需要修改它的访问权限(没有安全管理器时很容易做到)

classes = ClassLoader.class.getDeclaredField("classes");

classes.setAccessible(true);

List ret=(List) classes.get(cl); //classes是一个Vector

可惜的是对于引导类加载器没有办法获得加载的类,因为它是c实现的,在java中很难控制

javaextdir的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、javaextdir的信息别忘了在本站进行查找喔。

The End

发布于:2022-11-26,除非注明,否则均为首码项目网原创文章,转载请注明出处。