想学 Java 的人,十有八九都会在第一步“装环境”上浪费掉半天时间,然后在第一个 Java 程序跑起来之前,就已经开始怀疑人生了。标题里的“JavaSE基础02”看着平平无奇,其实就是从零到能跑通第一个程序、看懂基本语法的关键一步。这篇文章不讲虚的,我把从下载 JDK、配环境变量到写完第一个类的完整过程,以及后续学习中最容易卡壳的语法点,一次性给你捋清楚。这篇内容适合完全零基础的小白,也适合那些之前装过环境但老是出莫名其妙问题的朋友,按着步骤走一遍,你会发现 Java 入门没那么多玄学。
1. 环境准备与JDK选型:别再用教学视频里的老古董了
1.1 JDK、JRE、JVM 的关系,一次搞清楚
很多新手第一次搜 Java 环境搭建,会看到一堆名词:JDK、JRE、JVM、OpenJDK、Oracle JDK……直接劝退。其实拿做饭来类比就很好懂:JVM(Java Virtual Machine)是灶台,负责真正把菜煮熟,也就是运行 Java 程序;JRE(Java Runtime Environment)是厨房,除了灶台,还配好了锅碗瓢盆和调料,也就是 Java 程序运行所需的类库和工具;JDK(Java Development Kit)是整个厨房加上菜谱和刀工教程,它是给“做菜的人”也就是程序员用的,除了能运行程序,更重要的是能用javac命令把源码编译成字节码。
所以在开发阶段,我们装的是JDK而不是 JRE。JDK 内部自带一套 JRE,所以你装完 JDK 就不需要再额外装 JRE 了,装了反而容易出现 PATH 指向混乱的问题。我自己见过不少初学者装了 JDK 又把 JRE 单独装一遍,结果命令行里java -version显示的版本和javac -version对不上,排查了半天才发现是 JRE 的路径在捣乱。
1.2 JDK 版本怎么选:17 是当前最省心的版本
版本选择是很多人纠结的点。现在都出到 Java 21 甚至更新版本了,我是不是该装最新的?我的建议很明确:新手直接从 JDK 17 开始,不要碰 8,也不要追最新。Java 8 是老一代的主流,很多教学视频还在用,但它太老了,现在新项目新特性基本都围绕 17 及以后的长期支持版本展开;而 21 虽然已经很成熟,但部分生态工具链、网上的教程资料还没完全跟上来。
17 是长期支持版本(LTS),意味着有稳定的更新和维护,Spring Boot 3.x 也要求基于 17,现在招聘市场上大部分 Java 岗位的要求也是 17 起步。更重要的是,我用 17 实测下来,编译速度、内存占用、启动速度都明显优于 8,而且新的 switch 表达式、文本块这些语法写起来真的很舒服,能让你从一开始就养成良好的现代 Java 编码习惯。
注意:如果你是为了应付学校考试或看老视频,非要用 JDK 8,那也不是不行,但建议学完基础后尽快切到 17。否则你会在 lambda 表达式、
var关键字这些现代特性上感受到深深的代沟。
1.3 Oracle JDK 和 OpenJDK 的纠葛与账号问题
关于“javase 下载账号”这个热词,我多说一句。去 Oracle 官网下载 JDK 的时候,确实会遇到“需要登录 Oracle 账号才能下载”的提示,很多人卡在这一步。实际上,从 JDK 8 之后的某个版本开始,Oracle 官方对 JDK 的下载增加了账号验证,而且 Oracle JDK 的许可协议也更严格。对于学习和开发来说,我强烈建议直接用 OpenJDK,它和 Oracle JDK 在核心 API 上几乎没有区别,但下载完全免费,不需要注册账号不需要登录。如果你的机器上已经有 Oracle 账号,那下载也很顺手,但没必要为了下载单独注册一个。
当然,如果你在 Windows 上,最简单粗暴的方式其实是去微软的 OpenJDK 页面下载 Microsoft Build of OpenJDK,或者用包管理器直接装。在 Windows 上可以用 winget install Microsoft.OpenJDK.17,在 macOS 上更简单,一条 Homebrew 命令brew install openjdk@17,省去所有网页下载的麻烦。这对新手来说是最不容易出错的方式。
2. 环境变量配置详解:Path 和 JAVA_HOME 的底层逻辑
2.1 为什么要配环境变量:操作系统的“电话簿”
下载完 JDK,解压或安装到一个目录后,你以为就完了?还差关键一步——配置环境变量。Windows 系统里,当你在命令行敲java的时候,操作系统其实并不知道这个命令在哪个文件夹里,它只会去Path环境变量列出的目录里挨个找,找到了就执行,找不到就报“不是内部或外部命令”。
所以配环境变量的本质,就是告诉操作系统“java 这个程序住在哪”。类比一下,环境变量就是操作系统的电话簿,Path里存着各个程序的住址。你的新程序(JDK 里的 java.exe)如果没把自己登记进电话簿,别人就找不到它,自然也就没法运行。
2.2 一步步配置 JAVA_HOME、Path 和 CLASSPATH
具体到 Windows 上的操作,右键“此电脑”->“属性”->“高级系统设置”->“环境变量”。在系统变量区域,我给你一套实测最稳的方案:
第一步,新建一个系统变量,变量名写JAVA_HOME,变量值填你的 JDK 安装路径,比如C:\Program Files\Java\jdk-17.0.8。注意这里不要带bin子目录,JAVA_HOME 指向的是 JDK 的根目录。
第二步,找到Path系统变量,双击编辑,在列表最前方新增两行:%JAVA_HOME%\bin这样写的好处是之后如果你升级 JDK,只改 JAVA_HOME 这一个变量就行了,不用满世界去改 Path。
第三步(可选但建议),新建系统变量CLASSPATH,变量值填.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar。这里面的.代表当前目录,意思是让 JVM 能在当前路径下找类文件。不过在 JDK 9 之后,CLASSPATH 已经不强制配置了,我实测用 JDK 17 跑普通入门程序,不配 CLASSPATH 也完全没问题。所以新手可以跳过这步,免得配错了反而干扰。
2.3 验证环境是否配置成功:一行命令见分晓
配置完环境变量,必须重启命令行窗口(新打开一个 cmd),然后输入:
java -version javac -version如果能看到如下输出,说明环境已经通了:
java version "17.0.8" 2023-07-18 LTS Java(TM) SE Runtime Environment (build 17.0.8+9-LTS-211) Java HotSpot(TM) 64-Bit Server VM (build 17.0.8+9-LTS-211, mixed mode, sharing)这里有个常见坑:很多人配好后打开了新终端,结果输入java -version显示的还是旧版本,比如显示 1.8。这通常是因为原来的老 JDK 路径排在前面,你的 Path 里新加的%JAVA_HOME%\bin不在最前面,或者旧版本的 Path 项没删掉。解决方案很简单:把%JAVA_HOME%\bin移到 Path 列表的顶部,然后删掉其他 Java 相关的路径,比如C:\Program Files\Java\jdk1.8.0_131\bin这种。
提示:macOS/Linux 用户别急,原理完全相同,只是配置文件不同。在
~/.bash_profile或~/.zshrc里写三行:export JAVA_HOME=$(/usr/libexec/java_home -v 17)、export PATH=$JAVA_HOME/bin:$PATH,然后source ~/.zshrc就行。
3. 第一个 Java 程序到程序运行机制:亲手打破“只会抄代码”的魔咒
3.1 HelloWorld 的三种写法,从最规矩到最现代
环境通了,接下来就是那个每个程序员都逃不掉的 HelloWorld。很多教程直接让你新建一个文本文件,改后缀为.java,然后抄代码。但我要多讲一层,因为理解“编译——运行”这两个阶段比抄代码重要得多。
先在任意目录新建一个文件,命名为Hello.java,注意文件名必须和 public class 的类名完全一致,大小写都不能错。这是 Java 的硬性规定,因为 JVM 是通过文件名来找对应的类的。
用记事本或者 VS Code 写入:
public class Hello { public static void main(String[] args) { System.out.println("Hello, Java!"); } }然后在命令行切换到该文件所在目录,执行:
javac Hello.java你会看到目录里多了一个Hello.class文件,这就是字节码文件。接着执行:
java Hello屏幕上就会打印出Hello, Java!。注意,运行命令java Hello后面不带.class后缀,很多新手在这里会习惯性地写java Hello.class,结果报错错误: 找不到或无法加载主类 Hello.class,这个坑我见过了无数次。
如果你用的 JDK 11 及以上,还能直接运行单文件源码,省去显式编译步骤:
java Hello.java对于写小 demo 来说这个方式特别香,但我仍然建议你手动跑一遍javac再java的完整流程,因为这样你才能真正理解编译和运行是两个独立的阶段,后面学 IDE 里的一键运行时才不会一脸懵。
3.2 main 方法为什么签名必须是 public static void main(String[] args)
很多初学者对这个签名是死记硬背的,看到public static void main(String[] args)就头皮发麻。我来拆开解释一下,理解之后你永远都不会忘:
public:JVM 要从外部调用这个入口方法,必须是公开的,私有的话 JVM 进不去。static:JVM 在启动时还没有创建类的对象,它需要一个不用 new 就能调用的方法,所以必须是静态的。void:程序入口不需要返回值,跑完了就结束,返回给操作系统的是退出状态码,不是 Java 的返回值。main:这是 JVM 约定的入口方法名,相当于“电影院的安全出口”标识,固定不变。String[] args:这是从命令行传给程序的参数数组,运行时可以java Hello 参数1 参数2,在程序里用args[0]、args[1]取出来。
弄懂这个签名后,你对 JVM 是怎么启动一个 Java 程序的认知,至少超过一半的新手。
3.3 编译型还是解释型:Java 是两者结合的“混血儿”
为什么明明有javac把源码编译成 class 文件,java命令又要把 class 文件“解释”执行?这不是脱裤子放屁吗?其实是 Java 采用了编译和解释混合的模式。
javac做的编译,是把人类写的.java源码编译成 JVM 认识的字节码(.class),这一步和平台无关,字节码是统一的。到了java运行阶段,JVM 再把字节码解释成当前操作系统能执行的机器码。这正是 Java 号称“一次编写,到处运行”的根基——只要目标平台有对应的 JVM,同一份 class 文件就能跑。
而且现在的 HotSpot JVM 里还有 JIT(即时编译)技术,热点代码在运行时还会被进一步编译为本机机器码,运行效率并不输给纯编译型语言。所以 Java 的性能其实没有传说中那么差,你得从原理上理解它的设计哲学。
4. 核心语法基础:变量、数据类型的背后逻辑
4.1 基本数据类型和引用类型的区别,用两次赋值就能想明白
Java 是强类型语言,变量必须先声明类型再使用。基础的数据类型可以分为四类八种:整数类型(byte、short、int、long)、浮点类型(float、double)、字符类型(char)、布尔类型(boolean)。
其中int是默认的整数类型,范围在约 -21 亿到 21 亿之间,超出这个范围就得用long并加上 L 后缀;float和double的默认值是double,所以给 float 赋值要加 f 后缀;char用单引号包裹,String才是双引号,这个单双引号的区分是新手最常犯的错误之一。
引用类型的概念,我用一次赋值来说明。当你写int a = 10; int b = a; b = 20;,a 依然是 10,因为基本类型存的是值本身,赋值就是拷贝一份。但如果你用数组或对象,比如:
int[] arr1 = {1, 2, 3}; int[] arr2 = arr1; arr2[0] = 999; System.out.println(arr1[0]); // 输出 999arr1 的第一个元素也变成了 999,因为引用类型变量存的是对象的“住址”,arr1 和 arr2 指向同一块内存,改一个等于改另一个。理解了这个,后面学集合、对象传递的时候会少踩无数坑。
4.2 变量作用域和命名规范:给你的名字留点“心眼”
变量的作用域就是它所在的代码块(大括号)范围内。出了花括号,变量就消失了。很多人会在这个地方翻车:在一个 if 里定义了变量,出了 if 再访问,报“找不到符号”,然后怀疑人生。其实这就是作用域规则在起作用,不是编译器故意刁难你。
命名规范上,类名用大驼峰(HelloWorld),变量名和方法名用小驼峰(userName、getUserName),常量用全大写下划线分隔(MAX_COUNT)。这是行业通用的约定,不是说编译器强制,而是团队协作时的“通用语”。养成好习惯后,你在看别人的代码时一眼就能分清哪个是类、哪个是变量、哪个是常量。
4.3 String 不是基本类型,但它长得太像了
初学者容易将String误认为基本类型,因为它用起来太像了:可以直接String s = "hello";直接用双引号赋值,不需要new。但 String 实际上是一个引用类型,是一个不可变的类。
不可变意味着你不能“修改”一个字符串的内容,只能重新指向一个新的字符串对象。比如:
String s = "hello"; s = s + " world";表面上 s 变成了 "hello world",实际上是创建了一个新的字符串对象,然后让 s 指向它,原来的 "hello" 字符串还留在内存里等垃圾回收。为什么这么设计?因为字符串在 JVM 里用到极其频繁,不可变的设计可以保证线程安全、支持字符串常量池复用,还能用在 HashMap 的 key 上而不用担心被修改。
4.4 键盘输入Scanner:终于可以和程序交互了
跑通 HelloWorld 之后,最枯燥的阶段就算熬过去了,接下来就是可以“对话”的环节。用Scanner类,能让程序接收键盘输入,这是写第一个有交互感的小程序最实用的方式。
import java.util.Scanner; public class InputDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入你的名字:"); String name = sc.nextLine(); System.out.println("你好," + name + "!"); sc.close(); } }用nextLine()读取一行字符串,用nextInt()读取整数,用nextDouble()读取小数。有几个小细节要注意:nextInt()之后如果紧跟着nextLine(),中间的换行符会被后者吃掉,导致读不到内容。这是因为nextInt()只读了数字没读换行符,解决方法是再加一个nextLine()把换行符消耗掉。
另外用完 Scanner 建议关闭,释放底层的输入流,尤其是写更复杂的程序时这个习惯很重要。
5. 运算符和控制流程:写代码逻辑的“乐高积木”
5.1 几个容易踩坑的运算符细节
运算符是写程序的基础,但新手有好多容易在这里翻车的地方。我特别提醒三处:
一是整数除法。int a = 7 / 2;得到的是 3,不是 3.5。因为两个整数相除,结果会直接截断小数部分。想要得到小数,至少得让一边变成浮点数,比如7 / 2.0。
二是取模运算符%。它得到的是余数,可以用来做奇偶判断、环形数组下标切换等。比如i % 2 == 0判断偶数,或者让数组下标循环滚动。
三是自增自减的前置后置区别。int a = 5; int b = a++;此时 b 是 5,a 变成 6;int c = ++a;此时 a 先变成 7,c 也是 7。口诀是“++ 在前先加再用,++ 在后先用再加”,这个没搞清楚,面试笔试和日常代码都会埋雷。
5.2 if、switch 的新玩法:不止是“半斤八两”
控制流程里最常用的就是 if-else 和 switch。基础用法我就不重复了,只提两个容易忽略的细节。
if-else 的串行结构里,要注意条件的判断顺序。比如判断成绩等级时:
if (score >= 90) { System.out.println("优秀"); } else if (score >= 60) { System.out.println("及格"); } else { System.out.println("不及格"); }这里条件从大到小排列,能保证逻辑正确。如果你写成score >= 60在前,那 90 分以上的也会走到“及格”分支,这就是典型的逻辑漏洞。
switch 在 JDK 14 之后支持了箭头语法,可以不写 break,也不会穿透。比如:
switch (day) { case 1 -> System.out.println("周一"); case 2 -> System.out.println("周二"); default -> System.out.println("其他"); }这种写法比传统的 break 写法简洁很多,也省去了漏写 break 导致 fall-through(穿透执行)的经典 bug。如果你还是 JDK 8,老老实实写 break,但如果你已经切到 17,请用箭头语法。
5.3 循环三兄弟:for、while、do-while 的选用场合
for循环适合知道循环次数的场景,比如遍历数组,for (int i = 0; i < arr.length; i++)。while循环适合不知道次数、只依赖某个条件的场景,比如读取文件直到末尾。do-while的特点是至少执行一次,再判断条件,适合“先执行一次再问用户是否继续”的场景。
实际写代码时,还有一个容易忽略的点:在循环里用break跳出循环,用continue跳过本次循环的剩余代码进入下一次。这两个词在嵌套循环里只作用于最近的一层循环,很多人以为 break 能把外层也跳了,结果发现循环还在跑,这一点在嵌套循环遍历二维数组时尤其要小心。
6. 方法:把复杂逻辑拆成小积木的艺术
6.1 方法的参数传递到底是值传递还是引用传递
几乎所有 Java 初学者都会遇到这个问题:“Java 到底是值传递还是引用传递?”标准答案是:Java 只有值传递。基本类型传的是值的拷贝,方法里面怎么改都不影响外面的变量;引用类型传的是“引用地址”的拷贝,方法里改这个对象的属性会影响外部对象,但如果在方法里把参数重新赋值为一个新对象,外部的引用不会变。
太多人把“引用类型作为参数”误认为是引用传递,其实不是。这里我用一个生活类比帮你锁死这个概念:你把自己家的地址写在一张纸条上递给朋友,朋友按地址去你家里搬走了一盆花,你会发现自己家的花没了;但如果朋友把纸条改成了另一个地址,你家的花不会受影响。地址的拷贝是值,地址指向的房子里的内容是共享的,这就是 Java 传参的本质。
6.2 方法重载与可变参数:同名不同面,参数随心配
方法重载(Overload)是指在同一个类中,可以定义多个同名方法,但参数列表必须不同(个数、类型或顺序不同)。调用时编译器会通过实参的类型来决定具体调用哪一个,这就是“编译期多态”。写重载方法时有个容易忽略的点:如果两个重载方法只差返回类型,比如一个返回 int 一个返回 void,那是不允许的,因为只靠返回类型无法区分调用的是哪个方法。
JDK 5 引入的可变参数也能让方法接收不定个数的参数,格式是public void printAll(String... names),在方法内部把 names 当数组用。可变参数必须放在参数列表的最后一位,这个限制要记住。在写工具类或者日志封装时,可变参数能省掉很多写数组创建代码的痛苦。
6.3 使用递归时,防爆栈是必须课
递归就是方法调用自身,解决“大问题拆成小问题”的场景,比如计算阶乘、斐波那契数列、遍历目录树。但递归有一个致命弱点:每调用一次方法,JVM 就会往栈里压入一个栈帧,深度过大就会抛StackOverflowError。
新手学递归最容易犯的错误是忘记写递归出口,代码跑起来直接 1 秒闪退,然后一脸懵。正确的写法一定要有一个终止条件,并且在递归调用时不断逼近这个条件。举个计算阶乘的例子:
public static int factorial(int n) { if (n == 1) { return 1; } return n * factorial(n - 1); }这里的n == 1就是递归出口。别看这个例子简单,它包含了递归的全部要素:边界条件、递归体、参数逼近。
7. 常见问题与排查技巧实录:新手翻车现场全记录
7.1 “找不到或无法加载主类”的三大原因
这个错误信息对 Java 初学者来说,出现频率极高。我总结下来无非三种原因:
一是运行命令写错,比如java Hello.class多了.class后缀,正确写法是java Hello。 二是类文件不在当前目录,运行java Hello时 JVM 只在 classpath 指定的路径找类文件,如果目录不对就会报这个错。解决办法是cd到 class 文件所在目录,或者用java -cp 目录 Hello指定。 三是包名问题,类所在包和命令中的类名对不上。如果你的类声明了package com.demo;,那 class 文件必须在com/demo目录结构下,运行命令也要跑到该目录的上一层,写java com.demo.Hello。
7.2 “编码错误”和乱码问题:记事本背锅现场
很多新手习惯用 Windows 记事本写 Java 源码,结果编译报错:错误: 编码 GBK 的不可映射字符。这是 Windows 简体中文环境下记事本默认用 GBK 编码,而 javac 默认以为是平台默认编码,然后源文件里的中文注释就出了幺蛾子。
解决思路有两个:一是换用 VS Code、IDEA 这类现代化编辑器,统一使用 UTF-8 编码;二是如果非要用记事本,在编译时显式指定编码,javac -encoding UTF-8 Hello.java。我强烈建议从第一天就用 VS Code 或 IntelliJ IDEA,不仅是为了中文注释,更是为了后面的代码提示和调试功能。
7.3 版本不一致的坑:装了两个 JDK 的“精神分裂”
这是我在帮读者排查时遇到最多的一个场景,症状表现如下:java -version显示 17,javac -version却显示 1.8。造成这种情况的原因通常是多个 JDK 并存,且java.exe和javac.exe来自不同目录。
排查方法其实很简单,在命令行分别执行:
where java where javac可以看到两个文件各自所在的路径。正常情况下两者应该指向同一个bin目录。如果不一样,要么删掉多余的 JDK,要么调整Path环境变量的顺序,把目标 JDK 的%JAVA_HOME%\bin提到最前面。
7.4 常见问题速查表
| 症状 | 最常见原因 | 解决思路 |
|---|---|---|
| 不是内部或外部命令 | Path 未配置或新终端没重启 | 检查 JAVA_HOME 和 Path,重开终端 |
| 找不到或无法加载主类 | 类名写错 / 目录不对 / 多了 .class | 确认文件名和类名一致,运行不带后缀 |
| 编码 GBK 不可映射字符 | 记事本默认 GBK 导致中文注释乱码 | 换 UTF-8 编辑器,或编译时加 -encoding UTF-8 |
| java 和 javac 版本不一致 | 多个 JDK 共存,PATH 顺序混乱 | 用 where 命令定位,统一指向一个版本 |
| 数组越界异常 | 循环条件写错,访问了下标外元素 | 检查循环边界,用i < arr.length代替i <= arr.length |
| 空指针异常 | 引用变量还没指向对象就调用方法 | 在使用引用前先判断是否为 null |
8. 小工具推荐:学习阶段让效率翻倍的组合方案
8.1 用 jshell 快速验证代码:别每次都开新工程
JDK 9 开始自带一个交互式工具 jshell,简直是小白的福利。以前你想验证一个语法,得建文件、写类、写 main、编译、运行,五步操作才能看到结果。现在只要在终端里敲jshell,就能直接输入语句看输出:
jshell> int a = 10; jshell> a * 2 $2 ==> 20这个工具特别适合我在上文谈到的语法点验证,比如想确认自增前置后置的区别,或者试试字符串拼接的效果,直接在 jshell 里试一下,比一遍遍开 IDEA 建类高效得多。
8.2 学习阶段用 VS Code 还是 IDEA
这个问题的答案分两种。如果你只是初学语法,建议用一个轻量编辑器 + 终端编译的组合,比如 VS Code 装上 Extension Pack for Java,它自带代码补全、语法高亮、调试支持,启动速度快,内存占用小,不至于让新手的注意力被工具本身带走。
如果你已经能流畅写一些简单程序,想走 Java 开发路线,那就直接上手 IntelliJ IDEA Community Edition(社区版免费),它对新手的感知很好,代码提示非常主动,重构功能强大。我第一次用 IDEA 的时候,感觉就像是学车从手动挡换到了自动挡,很多琐事都不用管了。
8.3 关于“javase下载账号”:学习资源获取的替代路径
既然刮到了这个热词,我就顺带聊一下。很多人在某搜索引擎里搜 javase 下载出来的都是各种需要注册登录门槛的站点。我的建议是学习阶段完全没必要在下载上纠结:OpenJDK 免费无门槛,微软和 Adoptium 都有现成的编译版本,下载速度也很快。所谓“javase 下载账号”其实是用某种搜索引擎找资源时遇到的注册门槛,换一个渠道,这个问题就不存在了。
学习资料方面,Oracle 官方有免费的 Java Tutorials,内容非常体系化,只是纯英文。中文环境的话,找一些口碑好的 Java 入门书籍比到处找的所谓“内部资源”靠谱得多。技术这行,最珍贵的从来不是找到一个下载链接,而是系统化的学习和足够的练习量。
这里我必须多说一句真心话。JavaSE 是整个 Java 生态的地基,地基牢不牢,直接决定你后面学 Spring、微服务能走多快。网上很多人鼓吹“Java 基础不重要,直接上手框架”,我见过不少被这种说法坑了的人,框架照着抄能运行,但一遇到报错就完全摸不着头脑,因为底层 Java 基础太薄弱了。反过来,基础扎实的人,框架对他们来说就是一堆封装好的工具,几天就能上手。
我自己的经历是,当年学 JavaSE 的时候对着 main 方法的签名抠了很久,不放过任何一个“为什么”,虽然当时感觉进度比别人慢,但现在回过头看,那些慢功夫全成了遮风挡雨的本钱。最后再给你一个掏心窝的建议:学完这些知识点后,别急着看下一个视频,亲手写一个小工具,比如一个计算器、一个猜数字游戏,把这些语法点都用一遍,比你光看两小时视频有用得多。Java 这行没有捷径,但脚踏实地的每一步,都会在之后的日子里加倍回馈你。