Java的类路径

和Java类路径(classpath)打交道的过程中,开发者偶尔会遇到麻烦。这是因为,类装载器实际装入的是哪一个类有时并不显而易见,当应用程序的classpath包含大量的类和目录时,情况尤其严重。本文将提供一个工具,它能够显示出被装入类文件的绝对路径名。
 
  一、Classpath基础
 
  Java虚拟机(JVM)借助类装载器装入应用程序使用的类,具体装入哪些类根据当时的需要决定。CLASSPATH环境变量告诉类装载器到哪里去寻找第三方提供的类和用户定义的类。另外,你也可以使用JVM命令行参数-classpath分别为应用程序指定类路径,在-classpath中指定的类路径覆盖CLASSPATH环境变量中指定的值。
 
  类路径中的内容可以是:文件的目录(包含不在包里面的类),包的根目录(包含已打包的类),包含类的档案文件(比如.zip文件或者.jar文件)。在Unix家族的系统上,类路径的各个项目由冒号分隔,在MS Windows系统上,它们由分号分隔。
 
  类装载器以委托层次的形式组织,每一个类装载器有一个父类装载器。当一个类装载器被要求装载某个类时,它在尝试自己寻找类之前会把请求先委托给它的父类装载器。系统类装载器,即由安装在系统上的JDK或JRE提供的默认类装载器,通过CLASSPATH环境变量或者-classpath这个JVM命令行参数装入第三方提供的类或者用户定义的类。系统类装载器委托扩展类装载器装入使用Java Extension机制的类。扩展类装载器委托自举类装载器(bootstrap class loader)装入核心JDK类。
 
  你可以自己开发特殊的类装载器,定制JVM如何动态地装入类。例如,大多数Servlet引擎使用定制的类装载器,动态地装入那些在classpath指定的目录内发生变化的类。
 
  必须特别注意的是(也是令人吃惊的是),类装载器装入类的次序就是类在classpath中出现的次序。类装载器从classpath的第一项开始,依次检查每一个设定的目录和压缩文件,尝试找出待装入的类文件。当类装载器第一次找到具有指定名字的类时,它就把该类装入,classpath中所有余下的项目都被忽略。
 
  看起来很简单,对吧?
 
  二、可能出现的问题
 
  不管他们是否愿意承认,初学者和富有经验的Java开发者都一样,他们都曾经在某些时候(通常是在那些最糟糕的情形下)被冗长、复杂的classpath欺骗。应用程序所依赖的第三方类和用户定义类的数量逐渐增长,classpath也逐渐成了一个堆积所有可能的目录和档案文件名的地方。此时,类装载器首先装载的究竟是哪一个类也就不再显而易见。如果classpath中包含重复的类入口,这个问题尤其突出。前面已经提到,类装载器总是装载第一个它在classpath中找到的具有合适名字的类,从实际效果看,它“隐藏”了其他具有合适名字但在classpath中优先级较低的类。
 
  如果不小心,你很容易掉进这个classpath的陷阱。当你结束了一天漫长的工作,最后为了让应用程序使用最好、最新的类,你把一个目录加入到了classpath,但与此同时,你却忘记了:在classpath的另一个具有更高优先级的目录下,存放着该类的另一个版本!
 
   三、一个简单的classpath工具
 
  优先级问题是扁平路径声明方法与生俱来固有的问题,但它不是只有Java的classpath才有的问题。要解决这个问题,你只需站到富有传奇色彩的软件巨构的肩膀上:Unix操作系统有一个which命令,在命令参数中指定一个名字,which就会显示出当这个名字作为命令执行时执行文件的路径名。实际上,which命令是分析PATH变量,然后找出命令第一次出现的位置。对于Java的类路径管理来说,这应该也是一个好工具。在它的启发之下,我着手设计了一个Java工具JWhich。这个工具要求指定一个Java类的名字,然后根据classpath的指引,找出类装载器即将装载的类所在位置的绝对路径。
 
  下面是一个JWhich的使用实例。它显示出当Java类装载器装载com.clarkware.ejb.ShoppingCartBean类时,该类第一次出现位置的绝对路径名,查找结果显示该类在某个目录下:
 
  > java JWhich com.clarkware.ejb.ShoppingCartBean
 
  Class 'com.clarkware.ejb.ShoppingCartBean' found in
  '/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class'
 
  下面是第二个JWhich的使用实例。它显示出当Java类装载器装载javax.servlet.http.HttpServlet类时,该类第一次出现位置的绝对路径名,查找结果显示该类在某个档案文件中:
 
  > java JWhich javax.servlet.http.HttpServlet
 
  Class 'javax.servlet.http.HttpServlet' found in
  'file:/home/mclark/lib/servlet.jar!/javax/servlet/http/HttpServlet.class'
 
  四、JWhich的工作过程
 
  要精确地测定classpath中哪一个类先被装载,你必须深入到类装载器的思考方法。事实上,具体实现的时候并没有听起来这么复杂——你只需直接询问类装载器就可以了!
 
  
public class JWhich {
  
  /**
  * 根据当前的classpath设置,
  * 显示出包含指定类的类文件所在
  * 位置的绝对路径
  *
  * @param className <类的名字>
  */
   public static void which(String className) {
  
   if (!className.startsWith("/")) {
   className = "/" + className;
   }
   className = className.replace('.', '/');
   className = className + ".class";
  
   java.net.URL classUrl =
   new JWhich().getClass().getResource(className);
  
   if (classUrl != null) {
   System.out.println(" Class '" + className +
   "' found in '" + classUrl.getFile() + "'");
   } else {
   System.out.println(" Class '" + className +
   "' not found in '" +
   System.getProperty("java.class.path") + "'");
   }
   }
  
   public static void main(String args[]) {
   if (args.length > 0) {
   JWhich.which(args[0]);
   } else {
   System.err.println("Usage: java JWhich ");
   }
   }
   }
 
 
  首先,你必须稍微调整一下类的名字以便类装载器能够接受(12-16行)。在类的名字前面加上一个“/”表示要求类装载器对classpath中的类名字进行逐字精确匹配,而不是尝试隐含地加上调用类的包名字前缀。把所有“.”转换为“/”的目的是,按照类装载器的要求,把类名字格式化成一个合法的URL资源名。
 
  接下来,程序向类装载器查询资源,这个资源的名字必须和经过适当格式化的类名字匹配(18-19行)。每一个Class对象维护着一个对装载它的ClassLoader对象的引用,所以这里是向装载JWhich类的类装载器查询。Class.getResource()方法实际上委托装入该类的类装载器,返回一个用于读取类文件资源的URL;或者,当指定的类名字不能在当前的classpath中找到时,Class.getResource()方法返回null。
 
  最后,如果当前的classpath中能够找到指定的类,则程序显示包含该类的类文件所在位置的绝对路径名(21-24行)。作为一种调试辅助手段,如果当前classpath中不能找到指定的类,则程序获取java.class.path系统属性并显示当前的classpath(24-28行)。
 
  很容易想象,在使用Servlet引擎classpath的Java Servlet中,或者在使用EJB服务器classpath的EJB组件中,上面这段简单的代码是如何运作。例如,如果JWhich类是由Servlet引擎的定制类装载器装入,那么程序将用Servlet引擎的类装载器去寻找指定的类。如果Servlet引擎的类装载器不能找到类文件,它将委托它的父类装载器。一般地,当JWhich被某个类装载器装入时,它能够找出当前类装载器以及所有其父类装载器所装入的所有类。
 
  【结束语】
 

 

  如果需要是所有发明之母,那么帮助我们管理Java类路径的工具可以说迟到了很长时间。Java新闻组和邮件列表中充塞着许多有关classpath的问题,现在JWhich为我们提供了一个简单却强大的工具,帮助我们在任何环境中彻底玩转Java类路径。
【生信】全基因组测序(WGS) 1、全基因组测序(WGS) 的定义 2、GWS流程 2.1准备工作——分析软件 2.2原始数据质控 2.3数据预处理 2.4变异检测 阅读详情

相关推荐

STM32移植u8g2库(HAL库)(硬件SPI)(sh1106_128x64)

STM32移植u8g2库(HAL库)(硬件SPI)(sh1106_128x64) MCU型号为STM32F103RCT6,OLED屏为中景园电子1.3寸屏,驱动芯片为sh1106,分辨率为128x64,MDK版本为V5.34。

Master_0_的博客 6272

Java相对路径与类路径详解

相对的是工作目录# 相对的是class文件所在的根目录# 相对的是ClassPathDemo.class所在的目录# 相对的是class文件所在的根目录,并且一定不能加斜杠。

小楼夜听雨的博客 1万+

告别Keil,在Windows上用VSCode + arm-none-eabi-gcc + Makefile搭建国产MCU开发环境(附JLink配置避坑)

本文详细介绍了如何在Windows上使用VSCode、arm-none-eabi-gcc和Makefile搭建国产MCU开发环境,替代传统的Keil和IAR。内容涵盖工具链配置、工程结构设计、Makefile编写、VSCode集成调试以及高效开发工作流,特别针对国产MCU如复旦微FM33系列提供了优化方案和避坑指南。

weixin_28729205的博客 434

java中的路径

在命令行运行java时,主要有2种路径。 一种是工作路径,也就是运行java XXX.class命令时所在的路径。此路径可通过 System.getProperty("user.dir") 来获取。 在java.io.File类中的相对路径就是基于此路径,源码: java.io.File#getAbsolutePath java.io.WinNTFileSystem#resolve(java.io.File) @Override public String resolve(Fil

yaoct的博客 8264

硬件原理图分析

文章目录1 硬件原理图分析1.1 MCU部分1.2 NB部分1.3 电源部分 1 硬件原理图分析 1.1 MCU部分 MCU接口部分没啥需要注意,都是常规操作。 1.2 NB部分 U4是用来防静电的。 由于NB的以上几个引脚只支持1.8V,所以这里需要3.3V转1.8V的电路。只要把握住谁改变电平就好分析是怎么实现电平转换的了。 1.3 电源部分 图中的MOS是用来实现USB和电池同时插入时只能USB供电功能的。 ...

木子皿--啥都不会的菜鸟 8170

本地化搭建DeepSeek+RAGFlow,构建个人知识库

本地化搭建DeepSeek+RAGFlow,构建个人知识库。至少32G以上内存、500G以上空余磁盘空间。

gogospecter的专栏 7428

Java的类路径究竟是什么?

它给出了三种可以作为类路径的的路径:1、应用程序的编译输出目录(通常是bin目录或target目录)。2、项目依赖的JAR文件,这些JAR文件通常放在lib目录下。(一个程序不可能只有程序员自己编码的一部分,还需要借助其他的轮子也就是我们的jar包来执行,这些jar包可以保存在lib目录下,也可以通过maven中的pom.xml文件来配置,3、其他任何在编译或运行时需要包含进来的目录或文件。

weixin_43836337的博客 1183

高性能优化的本质

在很早之前,处理器性能的提升一般是通过减小元器件的尺寸,增加元器件的数量,提高主频来实现,这也是摩尔定律所说的,但是由于功耗的影响,主频不能一直增加。后来,由于英伟达的GPU的并行计算的出现,逐渐打破摩尔定律,人们利用多核,SIMD,SIMT来处理大量相同计算的数据,这极大的提高了效率。计算机的算力得到了巨大的提升,但是并行是困难的,对于有数据依赖的程序来说,处理并行是一件及其困难的事,但对于一些简单的数学库的计算,并行的实现相对简单。

发狂的小花的博客 274

编程必备:如何在Java中设置类路径和工作目录

在 Java 编程中,类路径(Classpath)和工作目录(Working Directory)是两个非常重要的概念,它们对于程序的编译和运行至关重要。我将分别对这两个概念进行详细的介绍,并解释它们在 Java 开发中的作用和重要性。类路径(Classpath)类路径是 Java 运行时环境用来查找类和包的一个参数。简而言之,它是环境变量的一部分,指定了 JVM(Java虚拟机)搜索类定义的位置。类路径可以指向几种不同的数据源:可以是目录(其中包含了编译后的.class。

2401_83707780的博客 4052

Apifox接口测试+自动化测试

Apifox 接口测试+自动化测试快速入门!

程序员小杨哥的博客 1万+

从理论到实践:AI设备维护系统的架构实现

第一部分:理论基石——从设备维护的演进讲起,理解AI如何重塑维护模式;第二部分:架构设计——详解六层高可用系统架构,明确各层职责与技术选型;第三部分:核心技术——拆解数据处理、特征工程、模型训练、部署等关键环节的实现细节;第四部分:实践落地——8步流程带你从需求到上线,附代码示例与工具链;第五部分:案例研究——风电齿轮箱预测性维护系统的真实案例,从问题到方案再到效果;第六部分:挑战与展望——探讨当前技术瓶颈与未来趋势(数字孪生、联邦学习等)。准备好了吗?

大数据洞察的博客 1251

Java 类路径

Java中类存储在文件系统的子目录中,类的路径必须和包名匹配。 类文件也可以存储在JAR文件中,JAR文件使用ZIP格式组织文件和子目录,例如jre/lib/rt.jar中包含了数千个类库文件。 1 如何使你的类被多个程序共享 把类放到一个包树状结构的目录中,例如在/home/user/classdir中添加com.horstmann.corejava.Emplyee类,应该把Employee类文件放在/home/user/classdir/com/horstmann/corejava中 将JAR文件放在

weixin_42416780的博客 6497

SKILL 是什么?怎么做?五分钟 带你从入门到精通

skill-creator 是 Anthropic 官方开源的“元技能”——一个专门用来创建 Skill 的 Skill。你只需要用自然语言描述想要什么功能,它会自动生成。从更宏观的视角看,Skills 的出现标志着 AI 编程的一次范式转变。在传统的 AI 编程中,代码是确定性的:1 是 1,2 是 2。但到了大模型时代,代码变得不确定——你不知道模型会输出什么,不知道它会不会突然删掉几行代码。这种不确定性让很多开发者感到不安。Skills 把这套逻辑又拉了回来。

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 642

JAVA类路径

Java 类路径Java 类路径告诉 java 解释器和 javac 编译器去哪里找它们要执行或导入的类。类(您可能注意到的那些 *.class 文件)可以存储在目录或 jar 文件中,或者存储在两者的组合中,但是只有在它们位于类路径中的某个地方时,Java 编译器或解释器才可以找到它们。在 Windows 中,类路径中的多个项是用分号分隔( ;)的,而在 UNIX 中,这些项是用冒号分隔( :)

datouuupp的专栏 1万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

java类路径是什么_什么是类路径?

问题我刚读这行:format()方法的第一件事是从名为output.vm的类路径加载Velocity模板在这种情况下,我无法弄清楚classpath的含义。#1 热门回答(351 赞)在使用Java编程时,通过在源文件的顶部放置类似的内容,可以使其他类可用于你正在编写的类:import org.javaguy.coolframework.MyClass;或者有时你通过说:"大量导入"东西:impo...

weixin_35735685的博客 2113

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java类路径问题

Java类路径问题 注:类路径不仅仅作用于直接运行的类,import其中的类时,同样处理 详见:传送门 类路径相关问题 1、java命令是让虚拟机执行javac编译好的.class文件。虚拟机通过 classloader 来装载这些字节码, 也就是通常意义上的类。这里就有一个问题, classloader 从哪里知道 java 本身的类库及用户自己的类在什么地方呢? 答:缺省值 ( 当前路径 ) ,或者要有一个用户指定的变量来表明,这个变量就是环境变量:类路径 (classpath) ,或者在运行的时候传

weixin_44527182的博客 1082

[JAVA] JAVA 类路径

Java 类路径 类路径是所有包含类文件的路径的集合。 类路径中的目录和归档文件是搜寻类的起始点。 虚拟机搜寻类 搜寻jre/lib和jre/lib/ext目录中归档文件中所存放的系统类文件 搜寻再从搜寻类路径 测试搜寻类 Person.java 源文件 public class Person { private String name; public Perso...

diangang3082的博客 272

java添加类路径

给大家整理了一些有关【Java,命令行】的项目学习资料(附讲解~~):https://edu.51cto.com/course/35714.htmlhttps://edu.51cto.com/course/27963.htmlJava 添加类路径的详细指南 在 Java 开发中,类路径(Classpath)至关重要。它...

weixin_33104731的博客 243

java中类路径是什么_Java 类路径(学习 Java 编程语言 036)

类存储在文件系统的子目录中。类的路径必须与包名匹配。类文件也可以存储在 JAR(Java 归档)文件中。在一个 JAR 文件中,可以包含多个压缩形式的类文件和子目录,这样既可以节省空间又可以改善性能。在程序中用到第三方的库文件时,你通常要得到一个或多个需要包含的 JRE 文件。为了使类能够被多个程序共享,需要做到下面几点:把类放在一个目录中,例如 /home/user/classdir。需要注意,...

weixin_35965648的博客 2033

java设置类路径_Java 什么是类路径,该如何设置?

小编典典使用Java进行编程时,可以通过在源文件的顶部放置类似的代码来使其他类对正在编写的类可用:import org.javaguy.coolframework.MyClass;或者有时你通过说“批量导入”内容:import org.javaguy.coolframework.*;因此,稍后在你的程序中你说:MyClass mine = new MyClass();Java虚拟机将知道在哪里可以...

weixin_42352453的博客 1499

java类路径定制_设置Java类路径的注意事项

现在有一个JAVA项目,项目结构如图1所示。类Main依赖Log4J和Mysql-Connector包,“Base.java”文件只是最简单的类定义,“Main.java”文件内容如下:package com.dslztx.java;import org.apache.log4j.Logger;public class Main extends Base {private static final...

weixin_33205138的博客 396

JAVA 类路径

JAVA虚拟机规范(虚拟机规范链接百度传送门)并没有规定从何处寻找类,所以不同虚拟机实现方法可以不同。Oracle的虚拟机是根据类路径来搜索类。按照搜索的先后顺序,可以分为: 启动类路径(bootstrap classpath) 扩展类路径(extension classpath) 用户类路径(user classpath) 启动类路径默认在jre\lib目录下, java标准库(大部分在rt.jar里)位于该路径。 扩展类路径对应jre\lib\ext目录,使用java扩展机制的类位于这个路径。 我们自

cfuckfuck的博客 671

如何在 Java 中设置CLASSPATH类路径

环境变量,请在您的机器中找到用户环境变量的位置并添加存储Jar文件的所有路径。如果您的CLASSPATH环境变量设置为不正确的值,那么您可以取消设置CLASSPATH并为其指定空值。作为最佳实践,始终将所有JAR文件和应用程序类组织在一个根文件夹中。为了加载包含在子目录中的文件,必须在CLASSPATH中明确列出这些目录和/或文件。当您设置了应用程序运行时始终需要的jar文件的位置后,最好将它们添加到机器的环境变量。很多时候,您可能还需要在类路径中添加单独的类。...

allway2的博客 1万+

管理 Java 类路径 (Windows)

 类路径是 Java™ 平台中最复杂也最令人头痛的部分之一,但熟练掌握类路径对成为一名专业 Java程序员来说却又十分关键。在本文中,Elliotte Rusty Harold 为您阐述了类路径和源路径的复杂性,并向您展示了如何在Windows 中熟练掌握它们。如果您使用的是 UNIX 或 Mac OS X,请参阅本文的 姊妹篇。类路径可以连接 Java 运行库和文件系统。

kinglino520的专栏 809

如何理解java的类路径

类路径(Classpath)在 Java 应用中是一个重要的概念,它指的是 Java 虚拟机(JVM)在运行程序时查找类文件和资源的目录集合。

qgqceo的博客 774
上一篇: 腾讯副总裁谈用户体验
下一篇: Ehcache配置文件的说明
helloman0908
博客等级 码龄16年 1粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值