第2章 Java 程序是怎么运行起来的
这一章只解决一个问题:你写的 Java 代码,到底是怎么跑起来的?
如果这个问题不清楚,后面很多概念都会很虚。比如你会不知道为什么要装 JDK,为什么运行前要编译,为什么有 .class 文件,为什么类名和文件名要一致,为什么有时会报"找不到主类"。
我们从一个最小程序开始。
一、写下第一个 Java 文件
创建文件:
text
Hello.java
写入:
java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello Java");
}
}
先不要急着背。我们先运行它。
在文件所在目录执行:
bash
javac Hello.java
java Hello
如果一切正常,你会看到:
text
Hello Java
这里有两个命令:
javac Hello.javajava Hello
它们不是一回事。
二、javac 做什么
javac 是 Java 编译器。它读取 .java 源码,生成 .class 字节码文件。
运行:
bash
javac Hello.java
目录里会多出:
text
Hello.class
执行过程:
#mermaid-svg-MolDTKzWvQp34SFu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MolDTKzWvQp34SFu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MolDTKzWvQp34SFu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MolDTKzWvQp34SFu .error-icon{fill:#552222;}#mermaid-svg-MolDTKzWvQp34SFu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MolDTKzWvQp34SFu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MolDTKzWvQp34SFu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MolDTKzWvQp34SFu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MolDTKzWvQp34SFu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MolDTKzWvQp34SFu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MolDTKzWvQp34SFu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MolDTKzWvQp34SFu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MolDTKzWvQp34SFu .marker.cross{stroke:#333333;}#mermaid-svg-MolDTKzWvQp34SFu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MolDTKzWvQp34SFu p{margin:0;}#mermaid-svg-MolDTKzWvQp34SFu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MolDTKzWvQp34SFu .cluster-label text{fill:#333;}#mermaid-svg-MolDTKzWvQp34SFu .cluster-label span{color:#333;}#mermaid-svg-MolDTKzWvQp34SFu .cluster-label span p{background-color:transparent;}#mermaid-svg-MolDTKzWvQp34SFu .label text,#mermaid-svg-MolDTKzWvQp34SFu span{fill:#333;color:#333;}#mermaid-svg-MolDTKzWvQp34SFu .node rect,#mermaid-svg-MolDTKzWvQp34SFu .node circle,#mermaid-svg-MolDTKzWvQp34SFu .node ellipse,#mermaid-svg-MolDTKzWvQp34SFu .node polygon,#mermaid-svg-MolDTKzWvQp34SFu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MolDTKzWvQp34SFu .rough-node .label text,#mermaid-svg-MolDTKzWvQp34SFu .node .label text,#mermaid-svg-MolDTKzWvQp34SFu .image-shape .label,#mermaid-svg-MolDTKzWvQp34SFu .icon-shape .label{text-anchor:middle;}#mermaid-svg-MolDTKzWvQp34SFu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MolDTKzWvQp34SFu .rough-node .label,#mermaid-svg-MolDTKzWvQp34SFu .node .label,#mermaid-svg-MolDTKzWvQp34SFu .image-shape .label,#mermaid-svg-MolDTKzWvQp34SFu .icon-shape .label{text-align:center;}#mermaid-svg-MolDTKzWvQp34SFu .node.clickable{cursor:pointer;}#mermaid-svg-MolDTKzWvQp34SFu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MolDTKzWvQp34SFu .arrowheadPath{fill:#333333;}#mermaid-svg-MolDTKzWvQp34SFu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MolDTKzWvQp34SFu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MolDTKzWvQp34SFu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MolDTKzWvQp34SFu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MolDTKzWvQp34SFu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MolDTKzWvQp34SFu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MolDTKzWvQp34SFu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MolDTKzWvQp34SFu .cluster text{fill:#333;}#mermaid-svg-MolDTKzWvQp34SFu .cluster span{color:#333;}#mermaid-svg-MolDTKzWvQp34SFu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MolDTKzWvQp34SFu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MolDTKzWvQp34SFu rect.text{fill:none;stroke-width:0;}#mermaid-svg-MolDTKzWvQp34SFu .icon-shape,#mermaid-svg-MolDTKzWvQp34SFu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MolDTKzWvQp34SFu .icon-shape p,#mermaid-svg-MolDTKzWvQp34SFu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MolDTKzWvQp34SFu .icon-shape .label rect,#mermaid-svg-MolDTKzWvQp34SFu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MolDTKzWvQp34SFu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MolDTKzWvQp34SFu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MolDTKzWvQp34SFu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Hello.java
源码
javac编译
Hello.class
字节码
.java 是人写的源码。
.class 是 JVM 能理解的字节码。
如果源码有语法错误,javac 阶段就会失败,不会生成 .class。
比如少写分号:
java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello Java")
}
}
再编译:
bash
javac Hello.java
你会看到类似:
text
error: ';' expected
这是编译错误。程序还没有运行,编译器已经发现代码不合法。
三、java 做什么
java 命令负责启动 JVM,并让 JVM 执行某个类里的 main 方法。
bash
java Hello
注意,这里写的是:
text
Hello
不是:
text
Hello.java
Hello.class
java Hello 的意思是:请 JVM 找到名为 Hello 的类,并执行它的 main 方法。
执行过程:
#mermaid-svg-cEY1HRITRyG4YBvM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cEY1HRITRyG4YBvM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cEY1HRITRyG4YBvM .error-icon{fill:#552222;}#mermaid-svg-cEY1HRITRyG4YBvM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cEY1HRITRyG4YBvM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cEY1HRITRyG4YBvM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cEY1HRITRyG4YBvM .marker.cross{stroke:#333333;}#mermaid-svg-cEY1HRITRyG4YBvM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cEY1HRITRyG4YBvM p{margin:0;}#mermaid-svg-cEY1HRITRyG4YBvM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cEY1HRITRyG4YBvM .cluster-label text{fill:#333;}#mermaid-svg-cEY1HRITRyG4YBvM .cluster-label span{color:#333;}#mermaid-svg-cEY1HRITRyG4YBvM .cluster-label span p{background-color:transparent;}#mermaid-svg-cEY1HRITRyG4YBvM .label text,#mermaid-svg-cEY1HRITRyG4YBvM span{fill:#333;color:#333;}#mermaid-svg-cEY1HRITRyG4YBvM .node rect,#mermaid-svg-cEY1HRITRyG4YBvM .node circle,#mermaid-svg-cEY1HRITRyG4YBvM .node ellipse,#mermaid-svg-cEY1HRITRyG4YBvM .node polygon,#mermaid-svg-cEY1HRITRyG4YBvM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cEY1HRITRyG4YBvM .rough-node .label text,#mermaid-svg-cEY1HRITRyG4YBvM .node .label text,#mermaid-svg-cEY1HRITRyG4YBvM .image-shape .label,#mermaid-svg-cEY1HRITRyG4YBvM .icon-shape .label{text-anchor:middle;}#mermaid-svg-cEY1HRITRyG4YBvM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cEY1HRITRyG4YBvM .rough-node .label,#mermaid-svg-cEY1HRITRyG4YBvM .node .label,#mermaid-svg-cEY1HRITRyG4YBvM .image-shape .label,#mermaid-svg-cEY1HRITRyG4YBvM .icon-shape .label{text-align:center;}#mermaid-svg-cEY1HRITRyG4YBvM .node.clickable{cursor:pointer;}#mermaid-svg-cEY1HRITRyG4YBvM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cEY1HRITRyG4YBvM .arrowheadPath{fill:#333333;}#mermaid-svg-cEY1HRITRyG4YBvM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cEY1HRITRyG4YBvM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cEY1HRITRyG4YBvM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cEY1HRITRyG4YBvM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cEY1HRITRyG4YBvM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cEY1HRITRyG4YBvM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cEY1HRITRyG4YBvM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cEY1HRITRyG4YBvM .cluster text{fill:#333;}#mermaid-svg-cEY1HRITRyG4YBvM .cluster span{color:#333;}#mermaid-svg-cEY1HRITRyG4YBvM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cEY1HRITRyG4YBvM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cEY1HRITRyG4YBvM rect.text{fill:none;stroke-width:0;}#mermaid-svg-cEY1HRITRyG4YBvM .icon-shape,#mermaid-svg-cEY1HRITRyG4YBvM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cEY1HRITRyG4YBvM .icon-shape p,#mermaid-svg-cEY1HRITRyG4YBvM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cEY1HRITRyG4YBvM .icon-shape .label rect,#mermaid-svg-cEY1HRITRyG4YBvM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cEY1HRITRyG4YBvM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cEY1HRITRyG4YBvM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cEY1HRITRyG4YBvM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} java Hello
启动JVM
加载Hello.class
寻找main方法
执行代码
如果你写:
bash
java Hello.java
就混淆了源码文件和类名。
四、JDK、JRE、JVM 的关系
学 Java 必须理解这三个词。
#mermaid-svg-R4osv0JxdM4JIQs8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-R4osv0JxdM4JIQs8 .error-icon{fill:#552222;}#mermaid-svg-R4osv0JxdM4JIQs8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-R4osv0JxdM4JIQs8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-R4osv0JxdM4JIQs8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-R4osv0JxdM4JIQs8 .marker.cross{stroke:#333333;}#mermaid-svg-R4osv0JxdM4JIQs8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-R4osv0JxdM4JIQs8 p{margin:0;}#mermaid-svg-R4osv0JxdM4JIQs8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 .cluster-label text{fill:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 .cluster-label span{color:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 .cluster-label span p{background-color:transparent;}#mermaid-svg-R4osv0JxdM4JIQs8 .label text,#mermaid-svg-R4osv0JxdM4JIQs8 span{fill:#333;color:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 .node rect,#mermaid-svg-R4osv0JxdM4JIQs8 .node circle,#mermaid-svg-R4osv0JxdM4JIQs8 .node ellipse,#mermaid-svg-R4osv0JxdM4JIQs8 .node polygon,#mermaid-svg-R4osv0JxdM4JIQs8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-R4osv0JxdM4JIQs8 .rough-node .label text,#mermaid-svg-R4osv0JxdM4JIQs8 .node .label text,#mermaid-svg-R4osv0JxdM4JIQs8 .image-shape .label,#mermaid-svg-R4osv0JxdM4JIQs8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-R4osv0JxdM4JIQs8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-R4osv0JxdM4JIQs8 .rough-node .label,#mermaid-svg-R4osv0JxdM4JIQs8 .node .label,#mermaid-svg-R4osv0JxdM4JIQs8 .image-shape .label,#mermaid-svg-R4osv0JxdM4JIQs8 .icon-shape .label{text-align:center;}#mermaid-svg-R4osv0JxdM4JIQs8 .node.clickable{cursor:pointer;}#mermaid-svg-R4osv0JxdM4JIQs8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-R4osv0JxdM4JIQs8 .arrowheadPath{fill:#333333;}#mermaid-svg-R4osv0JxdM4JIQs8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-R4osv0JxdM4JIQs8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-R4osv0JxdM4JIQs8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-R4osv0JxdM4JIQs8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-R4osv0JxdM4JIQs8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-R4osv0JxdM4JIQs8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-R4osv0JxdM4JIQs8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-R4osv0JxdM4JIQs8 .cluster text{fill:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 .cluster span{color:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-R4osv0JxdM4JIQs8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-R4osv0JxdM4JIQs8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-R4osv0JxdM4JIQs8 .icon-shape,#mermaid-svg-R4osv0JxdM4JIQs8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-R4osv0JxdM4JIQs8 .icon-shape p,#mermaid-svg-R4osv0JxdM4JIQs8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-R4osv0JxdM4JIQs8 .icon-shape .label rect,#mermaid-svg-R4osv0JxdM4JIQs8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-R4osv0JxdM4JIQs8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-R4osv0JxdM4JIQs8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-R4osv0JxdM4JIQs8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} JDK
开发工具包
JRE
运行环境
JVM
Java虚拟机
javac编译器
其他开发工具
JVM
JVM 是 Java Virtual Machine,Java 虚拟机。它执行 .class 字节码。
JRE
JRE 是 Java Runtime Environment,Java 运行环境。它包含 JVM 和运行 Java 程序需要的基础类库。
JDK
JDK 是 Java Development Kit,Java 开发工具包。它包含 JRE,还包含 javac 等开发工具。
写 Java 需要 JDK。只运行 Java 程序理论上 JRE 就够,但现在日常开发基本都安装 JDK。
检查命令:
bash
java -version
javac -version
如果 java 有,javac 没有,说明 JDK 配置可能有问题。
五、为什么 Java 要多一步编译
有些语言可以直接解释执行。Java 通常先编译成字节码,再由 JVM 执行。这样设计有几个好处。
1. 提前发现错误
类型错误、语法错误可以在编译阶段发现。
java
int age = "18";
这段代码编译不过,因为字符串不能直接赋给 int。
2. 跨平台
同一份 .class 可以在不同系统上的 JVM 中运行。
#mermaid-svg-sTABA18InOalIRrI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sTABA18InOalIRrI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sTABA18InOalIRrI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sTABA18InOalIRrI .error-icon{fill:#552222;}#mermaid-svg-sTABA18InOalIRrI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sTABA18InOalIRrI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sTABA18InOalIRrI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sTABA18InOalIRrI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sTABA18InOalIRrI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sTABA18InOalIRrI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sTABA18InOalIRrI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sTABA18InOalIRrI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sTABA18InOalIRrI .marker.cross{stroke:#333333;}#mermaid-svg-sTABA18InOalIRrI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sTABA18InOalIRrI p{margin:0;}#mermaid-svg-sTABA18InOalIRrI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sTABA18InOalIRrI .cluster-label text{fill:#333;}#mermaid-svg-sTABA18InOalIRrI .cluster-label span{color:#333;}#mermaid-svg-sTABA18InOalIRrI .cluster-label span p{background-color:transparent;}#mermaid-svg-sTABA18InOalIRrI .label text,#mermaid-svg-sTABA18InOalIRrI span{fill:#333;color:#333;}#mermaid-svg-sTABA18InOalIRrI .node rect,#mermaid-svg-sTABA18InOalIRrI .node circle,#mermaid-svg-sTABA18InOalIRrI .node ellipse,#mermaid-svg-sTABA18InOalIRrI .node polygon,#mermaid-svg-sTABA18InOalIRrI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sTABA18InOalIRrI .rough-node .label text,#mermaid-svg-sTABA18InOalIRrI .node .label text,#mermaid-svg-sTABA18InOalIRrI .image-shape .label,#mermaid-svg-sTABA18InOalIRrI .icon-shape .label{text-anchor:middle;}#mermaid-svg-sTABA18InOalIRrI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sTABA18InOalIRrI .rough-node .label,#mermaid-svg-sTABA18InOalIRrI .node .label,#mermaid-svg-sTABA18InOalIRrI .image-shape .label,#mermaid-svg-sTABA18InOalIRrI .icon-shape .label{text-align:center;}#mermaid-svg-sTABA18InOalIRrI .node.clickable{cursor:pointer;}#mermaid-svg-sTABA18InOalIRrI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sTABA18InOalIRrI .arrowheadPath{fill:#333333;}#mermaid-svg-sTABA18InOalIRrI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sTABA18InOalIRrI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sTABA18InOalIRrI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sTABA18InOalIRrI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sTABA18InOalIRrI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sTABA18InOalIRrI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sTABA18InOalIRrI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sTABA18InOalIRrI .cluster text{fill:#333;}#mermaid-svg-sTABA18InOalIRrI .cluster span{color:#333;}#mermaid-svg-sTABA18InOalIRrI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sTABA18InOalIRrI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sTABA18InOalIRrI rect.text{fill:none;stroke-width:0;}#mermaid-svg-sTABA18InOalIRrI .icon-shape,#mermaid-svg-sTABA18InOalIRrI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sTABA18InOalIRrI .icon-shape p,#mermaid-svg-sTABA18InOalIRrI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sTABA18InOalIRrI .icon-shape .label rect,#mermaid-svg-sTABA18InOalIRrI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sTABA18InOalIRrI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sTABA18InOalIRrI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sTABA18InOalIRrI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Hello.class
Windows JVM
macOS JVM
Linux JVM
你写的是 Java,真正和操作系统打交道的是 JVM。
3. 支持大型工程
Java 的编译、包、类、依赖管理,让大型项目更容易组织。虽然入门时显得麻烦,但这是工程化能力的一部分。
六、public class 和文件名为什么要一致
文件:
text
Hello.java
代码:
java
public class Hello {
}
如果你写:
java
public class Demo {
}
但文件叫:
text
Hello.java
编译会报错:
text
class Demo is public, should be declared in a file named Demo.java
意思是:public 类 Demo 应该放在 Demo.java 文件里。
先记规则:
text
public 类名 = 文件名去掉 .java
一个文件里最多只能有一个 public 顶级类。以后大型项目里,一个类通常一个文件。
七、main 方法为什么长这样
java
public static void main(String[] args)
这一行初学时最吓人。先拆成几块。
main
main 是方法名。JVM 约定从这个方法开始执行。
如果你写成:
java
public static void start(String[] args)
编译可以过,但运行时 JVM 找不到 main 入口。
String\[\] args
这是命令行参数。运行程序时可以传入:
bash
java Hello Tom 18
这些参数会进入 args 数组。
public static void
这三个词后面会详细讲。
现在先建立直觉:
public:JVM 可以访问这个方法。static:不需要创建对象就能调用。void:方法没有返回值。
第一阶段先把 main 当成固定入口。等学到方法、类和对象,再把它完全拆开。
八、命令行参数实战
代码:
java
public class ArgsDemo {
public static void main(String[] args) {
System.out.println("参数个数:" + args.length);
for (int i = 0; i < args.length; i++) {
System.out.println("第" + i + "个参数:" + args[i]);
}
}
}
编译:
bash
javac ArgsDemo.java
运行:
bash
java ArgsDemo Tom 18 Shanghai
输出:
text
参数个数:3
第0个参数:Tom
第1个参数:18
第2个参数:Shanghai
注意:所有命令行参数默认都是字符串。18 进入程序后也是字符串 "18",不是数字 18。
如果要转成数字:
java
int age = Integer.parseInt(args[1]);
如果传入的不是数字:
bash
java ArgsDemo Tom abc
转换时会报:
text
NumberFormatException
这就是运行时错误:代码编译通过,但运行过程中数据不符合预期。
九、package 和 classpath 的第一层理解
小程序可以没有 package:
java
public class Hello {
}
项目大了以后会用 package:
java
package com.example.course;
public class Hello {
public static void main(String[] args) {
System.out.println("Hello package");
}
}
文件路径通常对应:
text
src/com/example/course/Hello.java
编译:
bash
javac -d out src/com/example/course/Hello.java
运行:
bash
java -cp out com.example.course.Hello
这里:
-d out表示把编译结果放到 out 目录。-cp out表示 classpath 是 out,JVM 去 out 里找类。com.example.course.Hello是完整类名。
如果你只写:
bash
java Hello
JVM 找不到,因为这个类的完整名字不是 Hello,而是 com.example.course.Hello。
入门阶段先知道:package 会影响类的完整名字,classpath 会影响 JVM 到哪里找类。
十、常见错误排查
1. 找不到 javac
text
command not found: javac
原因可能是:
- 没装 JDK。
- 装了但环境变量没配置。
- 终端没有重新打开。
先运行:
bash
java -version
javac -version
2. 类名和文件名不一致
text
class Hello is public, should be declared in a file named Hello.java
检查 public 类名和文件名。
3. 找不到主类
text
Error: Could not find or load main class Hello
检查:
- 是否已经
javac Hello.java。 - 当前目录是否有
Hello.class。 - 运行时是否写了正确类名。
- 如果有 package,是否写完整类名。
- classpath 是否正确。
4. 找不到 main 方法
text
Main method not found in class Hello
检查 main 是否写成:
java
public static void main(String[] args)
大小写、参数、static 都不要乱改。
5. 编译错误和运行错误混淆
编译错误发生在:
bash
javac Hello.java
运行错误发生在:
bash
java Hello
先判断错误发生在哪一步,排查会快很多。
十一、本章练习
-
创建
Hello.java,输出自己的名字。 -
故意删除分号,观察编译错误。
-
故意把文件名改成
Demo.java,但类名仍然是Hello,观察错误。 -
写
ArgsDemo.java,运行:
bash
java ArgsDemo Java Course
观察参数输出。
- 创建带 package 的
Hello.java,用javac -d out和java -cp out运行。
十二、本章总结
这一章要真正掌握:
- Java 源码文件是
.java。 javac把源码编译成.class。java启动 JVM 执行 class。- JDK 包含开发工具,JVM 执行字节码。
- public 类名必须和文件名一致。
- main 方法是程序入口。
- 命令行参数进入
String[] args。 - package 会影响类的完整名字。
- classpath 决定 JVM 去哪里找类。
- 编译错误和运行错误要分开看。
如果你能不用 IDE,只靠命令行独立编译和运行这些例子,就说明你已经真正迈过 Java 入门第一关。