编译与运行
-
编译
编译就是将 java 源文件(.java)文件,通过编译器将其便以为 JVM 可以识别的字节码文件(.class)文件
在源文件目录下,通过 javac 编译工具就都可以对源文件进行编译
-
运行
有了字节码文件(.class)文件,通过 java.exe 对字节码文件进行执行,也就是.class 装载到 jvm 机执行
常见错误
了解编译与运行之后,很多同学就会在尝试的过程中发现一些问题,其中最常见的一个错误内容就是:
找不到或无法加载主类
导致这个错误主要有以下两个原因:
-
类名错误
- 在命令行运行java程序时,包含了扩展名.class
- 未指明全限定类名的包名或者运行路径错误
-
类所在位置未添加至类加载路径中
- 存在依赖外部jar包时,命令行运行只添加了外部jar包路径,没有当前目录路径,所以找不到类文件
命令行编译
此时 HelloWorld 所在路径如图所示
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, World!");
}
}
保存为 HelloWorld.java
在当前目录执行
生成字节码文件
此时编译时没有问题的
执行字节码文件,程序可以正常运行
这里要注意,java 命令执行程序时传入的是 main 函数所在类的名字,而不是 class 文件,也就是不要去执行java HelloWorld.class
这个命令,不然会出现报错
这个时候找的是 HelloWorld.class.class 这个文件,自然是不对的。
在代码上加上文件的默认包,代码如下
package com.hog.demo;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
执行 javac 编译与 java 执行,会发现,程序无法执行,并给出信息:找不到或无法加载主类
这个错误是很多人都会遇到的一个问题。
搞清楚这个问题就需要知道,Java 是如何识别一个类文件的,在运行 java 程序时,是以全限定类名(包名+类名)来唯一确定一个文件
- 在 demo 目录运行
java HelloWorld
命令
F:\helloworld\com\hog\demo>java HelloWorld
这时会在当前目录下找HelloWorld
类,加了 package 语句后,只能发现com.hog.demo.HelloWorld
的类,与HelloWorld
不是同一个类,所以会出现运行错误的信息。
- 在 demo 目录运行
java com.hog.demo.HelloWorld
命令
F:\helloworld\com\hog\demo>java com.hog.demo.HelloWorld
这时,很自然的会想到,如果想要运行加了包名的HelloWorld
类,就需要运行java com.hog.demo.HelloWorld
这个命令,但是依旧会出现错误:找不到或无法加载主类,这是因为执行 java 命令依旧是在 demo 目录下执行的,这时候,java 会从当前目录找\com\hog\demo\下(f:\helloworld\com\hog\demo\com\hog\demo\)的 HelloWorld 文件,自然也是不存在的
- 在 helloworld 目录运行
java com.hog.demo.HelloWorld
命令
运行这个命令需要在 helloworld 目录下执行,这时候找到的路径就是正确的,即 f:\helloworld\com\hog\demo\HelloWorld
类路径 CLASSPATH
首先明确一点,jdk1.5 之后不建议用配置环境变量的方法来指定类加载路径,取而代之的是用 java 命令的-cp
或-classpath
参数指定。
语法格式:
- java -cp <路径 1;路径 2;…>全限定路径
- 路径:依赖的文件所在的绝对路径(或相对路径),如果类文件在 jar 包中,路径后还需要写上 jar 包的名字
.
代表当前路径,即 java 命令运行时所在路径
注意
当存在依赖外部 jar 包时,命令行运行 java 命令,classpath 参数中只是添加了外部 jar 包路径,没有添加当前目录.
,导致要运行的类文件找不到
在命令行运行程序时,存在外部依赖,不仅要在-cp 中知名依赖的路径,还有要把当前的路径加进去
java -cp .;./jar包
javac
Orcale 官方介绍 javac 的描述如下:
Reads Java class and interface definitions and compiles them into bytecode and class files.
javac 的语法如下:
javac [options][sourcefiles][classes][@argfiles]
基本用法:
-
-cp
参数设置类路径,基本用法是将编译时依赖的 jar 包加入类路径,并可用*
通配.jar 包 -
-d
参数用来设置 class 文件编译到单独目录,并根据包名创建子目录 -
可以通过 find 命令将文件列表输出文件中,通过@argfiles 参数传递