大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
基本语法与 main
这一课你将能做到
- 逐词解释
public static void main(String[] args)每个部分的作用,不再靠背 - 独立写出一个带包声明、注释、多条语句的完整 Java 文件并编译运行
- 按团队规范命名类、变量、方法、常量,代码风格和本站后端工程保持一致
为什么要学
Java 是「一切皆对象」的语言:哪怕只打印一句话,也必须先有类、类里必须有 main 方法。本站后端每个 Spring Boot 启动类的入口,就是 main:
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
这一课就是拆解这行代码背后的全部规则:类怎么声明、语句怎么结束、代码块怎么划分、名字怎么起。规则不多,但错一个都跑不起来——语法是后面 12 课的地基。
先建立图像
一个 Java 文件从上到下的固定层次:
Hello.java
├── package com.roadmap.demo; ← 可选:这个类属于哪个包(文件夹)
├── import java.util.List; ← 可选:要用到哪些外部类
└── public class Hello { ← 类:代码必须装在类里
├── 字段(以后学)
└── public static void main(String[] args) { ← 方法:程序入口
└── 语句; ← 每条语句以分号结尾
}
}
包与文件夹的对应关系(本站后端工程就是这样组织的):
src/main/java
└── com/roadmap/user
├── UserController.java
├── UserService.java
└── User.java
跟着做
步骤 1:最小可运行程序
新建 Greet.java:
public class Greet {
public static void main(String[] args) {
System.out.println("Hello"); // 输出不换行用 print
System.out.print("Java");
System.out.print(" 17");
System.out.println(); // 空参 println 只换行
System.out.printf("JDK %d.%d%n", 17, 0); // 格式化输出
}
}
运行:java Greet.java,输出:
Hello
Java 17
JDK 17.0
步骤 2:逐词拆解 main
public static void main(String[] args)
│ │ │ │ └── 参数:字符串数组。命令行跟的参数会进来,
│ │ │ │ 比如 java Greet tom 20 时 args[0]="tom"
│ │ │ └── 方法名:JVM 固定找这个名字作为入口
│ │ └── 返回类型:不返回任何值(入口没有「上家」接结果)
│ └── 静态:JVM 启动时还没有对象,只能不依赖对象直接调用
└── 公开:任何地方(包括 JVM 本身)都能访问
改掉任何一个词(比如去掉 static),JVM 就报「main 方法不是 static」或「在类中找不到 main 方法」。
步骤 3:注释的三种写法
// 1. 单行注释:解释下一行干什么
/* 2. 多行注释:
可以写好几行,
注意不能嵌套 */
/**
* 3. 文档注释:javadoc 工具会提取成文档
* 本站后端 Service 方法上通常写这种,说明入参和返回值
*/
public class CommentDemo {
public static void main(String[] args) {
System.out.println("注释不影响运行"); // 行尾注释也常用
}
}
步骤 4:包声明与 import
新建目录 com/roadmap/demo(对应包路径),把下面的类放进去,存为 Order.java:
package com.roadmap.demo; // 必须是第一行有效代码
import java.time.LocalDate; // 导入标准库的类,一个 import 一个类
public class Order {
public static void main(String[] args) {
LocalDate today = LocalDate.now(); // 不 import 就要写全名 java.time.LocalDate
System.out.println("订单创建日: " + today);
}
}
在 com 的上一级目录运行:
java com/roadmap/demo/Order.java
# 或两步式:
javac -d out com/roadmap/demo/Order.java
java -cp out com.roadmap.demo.Order
输出:订单创建日: 2026-10-06(随当天日期变化)。
步骤 5:命名规范(本站后端团队约定)
public class NamingDemo { // 类名:大驼峰 PascalCase
static final int MAX_RETRY = 3; // 常量:全大写 + 下划线
static int requestCount = 0; // 变量/字段:小驼峰 camelCase
public static void main(String[] args) {
int userId = 1001; // 局部变量:小驼峰,见名知意
String userName = "tom";
requestCount++;
System.out.printf("用户 %s(id=%d),当前请求数 %d,重试上限 %d%n",
userName, userId, requestCount, MAX_RETRY);
}
}
输出:用户 tom(id=1001),当前请求数 1,重试上限 3。
规则:标识符由字母、数字、_、$ 组成,不能以数字开头,不能是关键字(int、class、public 等)。$ 语法合法但留给编译器生成代码用,别手写。
讲清楚要点
- Java 文件的最小单元是类:连
main都必须挂在某个类里,不存在「游离在类外的函数」。 - 语句以分号结束,代码块用花括号:花括号成对出现,建议随手补右括号再往里填内容。
main是 JVM 的约定入口:签名必须一字不差是public static void main(String[] args)(JDK 里varargs形式String... args也行),JVM 按这个名字和签名反射查找。- 包 = 命名空间 + 目录结构:全名 = 包名 + 类名(如
java.lang.String)。公司项目用「域名倒写」开头(com.roadmap.xxx)避免冲突。 - Java 是大小写敏感的:
User和user是两个东西;String的 S 大写是类型,写小写直接编译错。 - 一个文件最多一个 public 类,且文件名必须与它相同;可以有多个非 public 类。
你可能会懵的地方
-
String[] args平时没用到,能删吗? 签名里必须有它,JVM 按签名找方法。不传参数时它是个长度为 0 的空数组,不是 null。 -
为什么 main 必须 static? JVM 启动时只加载类,还没创建任何对象;static 方法属于类本身,不需要对象就能调用。非 static 方法必须先有对象才能调,鸡生蛋问题。
-
一个文件里写多个类行不行? 行,但最多一个 public。学习阶段单文件多类(非 public)很方便,
java Xxx.java也能跑;正式工程里一个文件一个类。 -
System.out.println这么长,是什么东西?System是标准库的类,out是它里面的一个静态字段(标准输出流对象),println是这个对象的方法。链条是「类.字段.方法」。 -
import 会不会影响性能? 不会。import 只是给编译器看的「简写说明」,编译后类都是按全名引用的。
import java.util.*按需导入也没性能损失,但为了可读性本站风格是一个一个显式导入。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 语句末尾忘写分号 | 编译错误:';' expected | 每条完整语句结尾补 ; |
Public class Hello | P 大写不是关键字 | 关键字全小写:public |
public void main(...) | JVM 找不到入口,运行时报错 | 补全 public static void main |
main(String args) | 签名不符,JVM 找不到 | 必须是 String[] args 或 String... args |
类名 orderService 文件名 OrderService.java | 编译失败 | public 类名与文件名严格一致 |
package 写在 import 之后 | 编译错误:package 必须最前 | 顺序固定:package → import → class |
变量名用 u1、a、temp2 | 三天后自己都看不懂 | userId、orderList 见名知意 |
卡点急救
- 报错「在类 X 中找不到 main 方法」:逐字核对签名
public static void main(String[] args),最常见的错误是漏了static或参数写成String args。 - 报错「类 X 是公共的,应在名为 X.java 的文件中声明」:改文件名,或去掉类的
public。 - 报错「程序包 X 不存在」:要么忘了 import,要么类名拼错。IDE 里光标放红色类名上按 Alt+Enter 自动导入。
- 命令行跑包内类报「找不到或无法加载主类」:必须在包根目录用全限定名运行:
java com.roadmap.demo.Order,且路径分隔符用/(Windows cmd 里 javac 用\,java 运行用.分隔包名)。
面试常问
-
main 方法可以被重载吗? 可以。JVM 只认
public static void main(String[])这个签名作为入口,其他重载版本只是普通方法,需要入口主动调用。 -
main 能改成非 static 吗?为什么? 不能。JVM 启动时只有类没有对象,入口必须不依赖实例——这正是 static 的语义。
-
Java 的命名规范?(考察代码素养) 类/接口大驼峰;方法/变量小驼峰;常量全大写下划线分隔;包全小写。团队内一致比「标准」本身更重要。
-
&和&&有什么区别?(语法细节高频)&&短路:左边为 false 时右边不执行;&两边都算。判断空指针时必须用&&短路保护,如user != null && user.isActive()。
自测三问
public static void main(String[] args)四个修饰/组成部分分别解决什么问题?- 包声明和 import 的书写顺序是什么?包名和目录结构什么关系?
- 下面的代码有几处语法问题:
public class demo { public void Main() { system.out.println("hi") } }
小结一句话
Java 程序 = 类里装方法、方法里装语句;main 是 JVM 约定死签名的唯一入口,包管组织、import 管引用、命名管可读性——这些规则贯穿本站后端每一个 .java 文件。
延伸
- Oracle:Java 语言基础
- 下一课:基本类型与引用类型——为什么
0.1 + 0.2 != 0.3,为什么后端 ID 字段一律用long,Integer的缓存陷阱。