背景
集成开发环境用多了,最近想学一下 java 基础,用命令行来编译和运行一下,发现举步维艰,于是,创作这篇文章与大家共享。
基础知识梳理
在写代码之前,我们先花点时间来了解一下 java 编译和运行的过程,如下图:
里面涉及到 两个 命令符:
-
javac: 将 java源文件(即 .java 文件)编译成 java字节码(即 .class文件);
作用:编译期就是将我们写的java源代码交给编译器执行的过程,起翻译的作用,该过程主要对java源代码的语法进行检查,如果没有语法错误,就将源代码编译成字节码文件。
- java : 启动 JVM ,加载并运行 .class 文件
作用:将字节码文件(.class文件)加载到内存中交给java虚拟机执行,直到程序执行结束的过程,该过程主要对程序的逻辑错误进行检查,如果没有逻辑错误,程序的功能得到实现,输出结果。
- 编译期和运行期的内存分配区别:①编译期只是在程序的字节码文件中产生一些控制程序运行时分配内存的指令,仅仅是知道内存分配的大小以及存放的位置,不做具体的分配操作。
②运行期才是对内存真正的分配,确定程序分配内存的大小,以及这些变量该存放内存的位置。
示例代码
第一步:java代码
下面这段示例代码可以说是非常简单了,main是一个入口函数,我们在搞清楚 java 代码 编译和运行 过程的同时,也来讲解一下 args 这个字符串数组参数,
其实 args 是一个命令行参数 , 装的是用户在命令行中输入的参数。
package test;
import java.util.Arrays;
public class array {
public static void main(String[] args){
System.out.println(Arrays.toString(args));
}
}
第二步:用 javac 编译源文件
这一步执行的前提是你环境变量配置好了。
javac test/array.java
javac 你要编译的的源文件,路径一定要搞对,否则找不到
执行完这个命令之后,你会在源文件的同级目录下发现多了一个 对应的 .class 文件
第三步:开启JVM , 运行程序
java test.array params1 params2
java 包名 [params|可选]
补充
不知道大家有没有注意过,你执行 " java 完整的包名 "的时候 ,你所在的目录是 src
我们可以做个试验,你返回 src 的上一层,执行 “java ./src/完整包名” 也是报 错误: 找不到或无法加载主类 ..src.test.changeData.class
这与 JVM 寻找 classpath 顺序有关。应当遵循如下寻找顺序:
现在我们假设classpath
是.;C:\work\project1\bin;C:\shared
,当JVM在加载abc.xyz.Hello
这个类时,会依次查找:
-
<当前目录>\abc\xyz\Hello.class
-
C:\work\project1\bin\abc\xyz\Hello.class
-
C:\shared\abc\xyz\Hello.class
注意到.
代表当前目录。如果JVM在某个路径下找到了对应的class
文件,就不再往后继续搜索。如果所有路径下都没有找到,就报错。
classpath
的设定方法有两种:
在系统环境变量中设置classpath
环境变量,不推荐;
在启动JVM时设置classpath
变量,推荐。
我们强烈不推荐在系统环境变量中设置classpath
,那样会污染整个系统环境。在启动JVM时设置classpath
才是推荐的做法。实际上就是给java
命令传入-classpath
或-cp
参数:
java -classpath .;C:\work\project1\bin;C:\shared abc.xyz.Hello
或者使用-cp
的简写:
java -cp .;C:\work\project1\bin;C:\shared abc.xyz.Hello
没有设置系统环境变量,也没有传入-cp
参数,那么JVM默认的classpath
为.
,即当前目录:
java abc.xyz.Hello
上述命令告诉JVM只在当前目录搜索Hello.class
有偿提问
如果大家觉得这篇文章帮助你了,可以支持一下。
有偿提问