- 浏览: 898063 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
小宇宙_WZY:
膜拜一下大神,解决了我一个大问题,非常感谢 orz
【解惑】深入jar包:从jar包中读取资源文件 -
JKL852qaz:
感谢,遇到相同的问题!
【解惑】深入jar包:从jar包中读取资源文件 -
lgh1992314:
为什么java中调用final方法是用invokevirtua ...
【解惑】Java动态绑定机制的内幕 -
鲁曼1991:
说的都有道理,protected只能被同一级包的类所调用
【解惑】真正理解了protected的作用范围 -
鲁曼1991:
...
【总结】String in Java
学Java有些日子了,一直都使用IDE来写程序。这样的好处就是能让我连如何用命令行编译,解释执行Java源代码都不知道,就更不清楚JDK中的编译器和虚拟机(包含字节码解释器)是如何定位到类文件的。悲哀呀.......
1、安装JDK,配置环境变量。
不将JDK所在的目录配置到系统环境变量中,系统怎么能找到JDK中的编译器,解释器在哪呀?如果不指明JDK的bin文件夹的位置,在shell中是无法找到javac/java命令的。这点就不多说了。
2、编译,解释执行Java程序。【 javac命令/java命令】
(1) Test.java源代码
//缺省包,该程序源代所在位置: e:/project/ Test.java
public class Test{
.....
public static void main(String[] args){
.....
}
}
编译命令: 【javac e:/project/Test.java 】 在e:/project目录下生成了Test.class
注意: ① 如果想要将Test.class生成在指定目录下,可以使用javac -d命令,如【 javac -d c:/ e:/project/Test.java 】 在c:/目录下生成T est.class(即e:/Test.class)
②
javac -cp 中的-cp并不是指定Test.java的目录,这一点不要误解了。-cp/-classpath只能是指定类文件(.class文件)的路径。上面的命令不能写成: java -cp e:/project Test.java
解释执行命令 : 【 j ava -cp e:/project Test】 将调用解释器执行e:/project中的Test.class字节码。
注意: ① -cp 是指定用户类文件的位置,比如上面的Test.class的位置。这里因为要寻找Test.class类文件,而不是Test.java源代码文件,所以要通过-cp指定。千万没有这样的执行命令: java e:/project/Test
(2) Test.java源代码
//缺省包,但源代码中引用了一个JAR包内的自定义类,这个JAR包位于c:/目录下
import net.single.util.SL; //导入自定义JAR包中的类
public class Test{
private SL aObject=new SL(); //初始化JAR中的SL类
public static void main(String[] args){
......
}
}
编译命令: 【 javac -cp c:/single.jar e:/project/Test.java】 在e:/project目录下生成了Test.class
注意: 如果当前你要编译的java文件中引用了其它的类,但该引用类的.class文件不在当前目录下(或在其他目录下,或在.zip/.jar内),这种情况下就需要在javac命令后面,加上-cp/-classpath参数来指明这些类的位置。 一般来说有三种指定方式:
①
绝对或相对路径:javac -cp c:/single.jar
Test
.java 或
javac -cp ../single.jar
Test
.java
(其中 .. 表示上一级目录
)
②
系统变量:javac -cp %CLASSPATH%
Test
.java (其中:%CLASSPATH%表示使用系统变量CLASSPATH的值进行查找,这里假设single.jar的路径就包含在CLASSPATH系统变量中)
③ 当前目录: javac -cp ./single.jar
Test.java (其中 . 表示当前目录
)
解释执行命令 :【 java -cp c:/single.jar;e:/project Test】
注意: ① -cp的路径不仅指定了所需要的single.jar的位置,还必须指出编译后的Test.class的位置。
② 类路径中的不同项目要用分隔符区分,Unix系统的分隔符是冒号(:),Windows的是分号(;)
(3) Test.java 源代码
//该类在net.single包中,类中没有引入其他目录下的自定义类
package net.single;
public class Test{
.....
public static void main(String[] args){
.....
}
}
编译命令:【javac -d . e:/project/Test.java 】
注意: ① 如果没有-d而直接编译javac e:/project/Test.java。将会在 e:/project 目录下直接生成一个Test.class,但此Test.class无法解释执行,因为它实际上在edu.single包中。所以必须将包一起编译出来,这里用了-d参数。
② 上面的编译结果将在e:/目录下 自动根据包的结构形式创建文件目录,e:/net/single/Test.class
解释执行命令
: 【java
-cp
e:/
net.single.Test
】
现在我们总结一下:
[a.] 没有IDE环境,编译一个大型项目是很困难的,因为必须把需要被其他类引用的类先编译,而且最好把包结构一起编译出来。所以一般命令格式如下:
编译: javac -cp (需要引入的类文件路径1;需要引入的类文件路径2;....) -d (编译出的类文件存放的位置目录) (待编译文件路径)
执行:
java
-cp
(需要解释执行的类文件路径) (带包的类文件)
例:现在要编译一个类源码: Test.java,其中该类位于E:/project/下
(1. Test源代码中使用了一个JAR包中的类,这个single.jar包位于C:/目录下。
(2. Test源代码中使用了一个自定义类Content,这个类的源代码Content.java位于E:/下
(3. Test所在包为net.single,Content所在包为net.single.cont
解决: 步1:由于Test使用了Content类,所以必须先编译Content,而且Content类在E:/目录下,而且 属于包net.single.cont
编译命令: javac -d . e:/Content.java
编译结果: 在Content.java的当前目录下生成了一个 net/single/cont/Content.class 文件(带包结构),即e:/net/single/cont/Content.class
步2:编译Test类,并指明所引入的single.jar包和Content.class的位置
编译命令: javac -cp c:/single.jar;e:/net/single/cont -d . e:/project/Test.java
编译结果: 在Test的上一级目录下生成了一个 net/single/Test.class 文件,即e:/ net/single/Test.class
步3:解释执行Test.class
执行命令: java -cp c:/single.jar;e:/ net.single.Test
3、编译器,虚拟机如何定位到类的
package net.single; import java.util.*; import net.single.util.*; public class Test{ //SingleUtil类在c:/single.jar中的net.single.util包下 private SingleUtil sut=new SingleUtil(); }
编译命令: javac -cp c:/single.jar -d . e:/project/Test.java
编译器首先找到e:/project/Test.java。然后对Test源代码进行编译,当编译到创建SingleUtil类对象的语句时,编译器要开始寻找SingleUtil.class的位置。编译器首先查找包含这个类的所有包的位置,并查询所有的import指令,确定其中是否包含了被引用了的类。
如上面的Test.java,编译器将试图查找java.lang.SingleUtil,java.util.SingleUtil,net.single.util.SingleUtil以及当前包中的SingleUtil(即net.single.SingleUtil)。编译器将在三个部分中查找类文件:
(1) 在JDK的lib目录下的标准类库文件中查找java.lang,java.util和net.single.util包。显然只能找到java.lang和java.util包。然后在这两个包中查找SingleUtil类文件。当然是找不到的。
(2) 在编译命令中-cp参数表明的类路径(C:/single.jar)下查找java.lang,java.util和net.single.util包。显然只能找到net.single.util包,然后在里面找到SingleUtil类文件。
(3) 在Test.java的当前目录下查找SingleUtil,也是没有的。
如果没有找到SingleUtil,或者找到多个SingleUtil。编译器报错。
评论
我想知道,项目中引入的jar包,被改名之后, import 引入关系依然成立.
这就是说,IDE认识的不是包名,而是具体的com.*.* .
你知道这里边的机制吗?
我想了解一下,谢谢.
发表评论
-
NIO
2010-08-05 10:36 0在JDK1.4以前,I/O输入输出处理,我们把它称为旧 ... -
【总结】Java线程同步机制深刻阐述
2010-05-16 10:21 6005全文转载:http://www.iteye ... -
【JDK优化】java.util.Arrays的排序研究
2010-05-12 21:06 9193作者题记:JDK中有很多算法具有优化的闪光点,值得好好研究。 ... -
【JDK优化】 Integer 自动打包机制的优化
2010-03-12 19:14 4204我们首先来看一段代码: Integer i=100; In ... -
【总结】Java与字符编码问题详谈
2009-12-30 09:11 9428一、字符集和字符编码方式 计算机只懂得0/1两种信号 ... -
【解惑】 正确理解线程等待和释放(wait/notify)
2009-12-29 13:40 19773对于初学者来说,下面这个例子是一个非常常见的错误。 /** ... -
【解惑】JVM如何理解Java泛型类
2009-12-16 11:08 12382//泛型代码 public class Pair<T& ... -
【解惑】正确的理解this 和 super
2009-12-05 09:46 4474转载: 《无聊 ... -
【解惑】真正理解了protected的作用范围
2009-11-21 18:00 5095一提到访问控 ... -
【总结】String in Java
2009-11-21 17:52 10988作者:每次上网冲杯Java时,都能看到关于String无休无止 ... -
【解惑】真正理解了protected的作用范围
2009-11-16 17:11 585一提到访问控制符protected,即使是初学者 ... -
总结Java标准类库中类型相互转化的方法
2009-11-09 21:57 210组一: ☆ String → byte[ ... -
方法没覆盖住带来的烦恼
2009-11-05 09:18 100Object类是所有类的祖宗,它的equals方法比较的 ... -
【解惑】数组向上转型的陷阱
2009-11-03 11:44 1890问题提出: 有两个类Manager和Em ... -
【解惑】剖析float型的内存存储和精度丢失问题
2009-10-26 15:10 16087问题提出:12.0f-11.9f=0.10 ... -
【解惑】领略内部类的“内部”
2009-10-19 15:38 3601内部类有两种情况: (1) 在类中定义一个类(私有内部类 ... -
【解惑】深入jar包:从jar包中读取资源文件
2009-10-08 21:13 65951我们常常在代码中读取一些资源文件(比如图片,音乐,文 ... -
【解惑】理解java枚举类型
2009-09-26 09:37 3427枚举类型是JDK5.0的新特征。Sun引进了一个全新的关键字e ... -
编写自己的equals方法
2009-09-20 14:18 129在我的《令人头疼的"相等"关 ... -
【解惑】Java类型间的转型
2009-09-11 16:03 5682★ 基本数据类型间的转换 1、Java要做到平台无关 ...
相关推荐
Java虚拟机(JVM,Java Virtual Machine)是Java平台的核心组成部分,它负责执行Java程序,为Java代码提供了跨平台的运行环境。Java虚拟机的概念始于Sun Microsystems,现在由Oracle公司继续发展和维护。JVM的设计...
总结,基于Java实现的C语言编译器项目是一个富有挑战性的任务,它涉及到编译原理的深度应用和Java技术的巧妙结合。通过这个项目,开发者不仅可以深化对编译器设计的理解,还能提升在Java语言和跨平台开发方面的技能...
JDK(Java Development Kit)是Java程序设计的核心,它包括Java编程语言、Java虚拟机(JVM)以及Java标准库。而JRE(Java Runtime Environment)是JDK的一个子集,它提供了Java程序运行时所需要的环境,包括Java...
Java实现Tiger语言编译器是一项涉及计算机科学与软件工程领域的复杂任务,主要涉及到编译原理、Java编程语言以及一种名为Tiger的语言。Tiger是一种教学目的的中级编程语言,设计用于展示现代编译器技术的关键概念。...
1. **Java虚拟机(JVM)**:Java小型Basic编译器是用Java语言写的,因此它可以在任何安装了Java运行环境(JRE)的计算机上运行,因为Java程序依赖JVM来执行。JVM使得Java具有跨平台性,即“一次编写,到处运行”。 ...
对于Java而言,编译器将Java源代码转换成字节码,这种字节码可以在任何安装了Java虚拟机(JVM)的平台上运行,体现了Java“一次编写,到处运行”的特性。 ### Java与编译器的关系 Java语言的编译器具有特殊性,...
**Java版PL0编译器**是一个实现编程语言解析与转换的工具,主要用来学习和理解编译原理。PL0是一种简单的、静态类型的、过程式的编程语言,它被设计成教学目的,便于理解和分析编译过程。在这个项目中,我们使用Java...
Java类文件反编译器是一种工具,主要用于将Java字节码(.class文件)转换回源代码(.java文件)。这种工具对于开发者来说非常有用,因为它允许他们查看和理解已经编译的Java程序的内部工作原理,特别是当原始源代码...
它详细阐述了Java虚拟机(JVM)的工作原理,包括内存管理、类加载机制、字节码执行以及垃圾回收等核心概念。深入理解这些知识点对于提升程序性能、解决运行时问题以及设计高效的应用程序至关重要。 1. **JVM架构** ...
通过学习《JAVA虚拟机解读入门》,你将能够了解JVM如何加载和解析类,以及类加载的双亲委托模型。你还将掌握栈帧的工作方式,理解方法调用和返回的过程。此外,书中还会详细介绍垃圾收集的工作原理,包括如何判断...
Java虚拟机是Java语言的核心组成部分,它负责解析和执行Java代码,实现跨平台的“一次编写,到处运行”。通过深入学习JVM,我们可以优化程序性能、解决内存泄漏问题,以及更好地理解和调试Java应用。 首先,我们要...
本文将深入探讨Java虚拟机中的类初始化以及加载器的父委托机制。 一、类的加载 类加载是JVM启动时或运行中根据需要动态加载类到内存中的过程。这个过程分为三个阶段:加载、链接和初始化。 1. 加载:JVM通过类...
本压缩包包含的文件详细阐述了Java编程语言的各个方面以及Java虚拟机(JVM)的工作原理。 **Java语言规范** Java语言规范定义了Java程序的语法、语义和程序行为。它涵盖了以下几个关键部分: 1. **基本概念**:...
在本项目中,"基于Java实现的C语言编译器【100012136】"是一个课程设计任务,目标是构建一个能够解析并处理C语言源代码的编译器。这个编译器的实现采用了Java编程语言,这使得它具有跨平台的能力,能够在多种操作...
3. **反编译过程**:反编译器首先解析.class文件中的字节码,然后根据JVM规范重建出类的结构,包括类名、方法、变量等。接着,它尝试恢复源代码的语句和表达式结构,这个过程可能不完美,因为字节码可能丢失了某些源...
Java虚拟机的运行过程包括加载、验证、准备、解析、初始化等阶段,其中最重要的是解释器和JIT(Just-In-Time)编译器。解释器将字节码逐行解释执行,而JIT编译器会在运行时将热点代码编译成机器码,以提高运行效率。...
3. **编译成字节码**:通过解析源代码,编译器生成中间表示(IR),然后将其转化为Java虚拟机(JVM)可理解的字节码。字节码是一种低级但平台无关的指令集,存储在.class文件中。 4. **优化**:为了提高程序的运行...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了运行环境。学习Java虚拟机对于深入理解Java程序的执行机制至关重要。这里我们将深入探讨Java虚拟机的几个关键知识点。 1. 类加载机制:Java程序...
下面我们将详细讨论Java类反编译器的工作原理、常用工具以及相关的知识点。 1. **Java字节码与反编译** Java程序在编译后会生成字节码,这是一种中间语言,由JVM(Java虚拟机)负责解释执行。字节码并不直接对应于...
这本书的编写基于《深入理解Java虚拟机》第二版以及相关的Java规范,旨在帮助读者深入理解JVM的工作原理,并通过实践来提升技能。 首先,我们要了解Java虚拟机(JVM)的角色。JVM是Java平台的核心组件,它负责执行...