Java 从零开始完整教程(小白也能看懂)
前面我们学了 JavaScript、Go、C/C++、汇编。这一篇学 Java——一门”写一次,到处跑”、火了二十多年还不过时的经典语言。
你可能听过”Java 太老了吧”,但现实是:全球后端系统、安卓开发、大厂核心业务,大量还是 Java。它语法严谨、生态庞大、工作机会多。学它,很值。
一、Java 是什么?为什么值得学?
Java 是 1995 年由 Sun 公司(后被 Oracle 收购)发布的面向对象编程语言。
三个核心特点
- 一次编写,到处运行:Java 代码编译成字节码,只要有 Java 虚拟机(JVM)就能跑——不管 Windows、Mac 还是 Linux
- 面向对象:和 C++ 一样用类(class)组织代码,但比 C++ 简单(没有手写指针、内存自动管理)
- 稳定可靠:严格的类型检查、自动垃圾回收(GC),适合开发大型企业系统
和其他语言对比
| 语言 | 运行方式 | 特点 |
|---|---|---|
| JavaScript | 浏览器/Node 解释执行 | 前端主力 |
| Go | 编译成原生程序 | 后端、并发强 |
| C/C++ | 编译成原生程序 | 快、底层、手动管内存 |
| Java | 编译成字节码,跑在 JVM | 跨平台、面向对象、生态大 |
一句话: Java 用”虚拟机”换来了跨平台和稳定,是后端开发的中坚力量。
二、装环境:JDK
Java 要运行需要 JDK(Java 开发工具包),它包含了编译工具(javac)和运行环境(JVM)。
安装 JDK
Windows: 去 Oracle 官网或 Adoptium(推荐,免费开源)下载 JDK 安装包,一路下一步,记得配置环境变量 JAVA_HOME。
macOS:
brew install openjdkLinux:
sudo apt updatesudo apt install openjdk-17-jdk验证安装
java -versionjavac -version两个命令都能看到版本号就装好了。
java:运行 Java 程序javac:编译 Java 程序
三、第一个程序:Hello World
Java 的规矩和别的语言不太一样,先看代码:
public class Hello { public static void main(String[] args) { System.out.println("你好,世界!"); }}编译并运行
javac Hello.java # 编译,生成 Hello.classjava Hello # 运行# 输出:你好,世界!关键规则(和别的不一样的地方)
- 文件名必须和类名一致:类叫
Hello,文件就必须叫Hello.java - main 是固定的写法:
public static void main(String[] args)是程序入口,一个字都不能错 - 输出用 System.out.println:类似 JS 的 console.log
每个 Java 程序必须有 main 方法,程序从它开始跑。
四、变量和数据类型
声明变量:类型在前
public class Variables { public static void main(String[] args) { int age = 18; // 整数 double price = 3.14; // 小数 char grade = 'A'; // 单个字符 boolean isOK = true; // 布尔 String name = "小明"; // 字符串(大写 S,是类)
System.out.println("年龄:" + age); System.out.println("名字:" + name); }}和 C/C++ 几乎一样的强类型写法,只是 String 是大写(它是类不是基本类型)。
基本数据类型(8 种)
| 类型 | 说明 | 例子 |
|---|---|---|
int | 整数 | 18 |
long | 大整数 | 9000000000L |
double | 小数 | 3.14 |
float | 单精度小数 | 3.14f |
char | 单个字符 | ’A’ |
boolean | 布尔 | true |
byte | 小整数 | 127 |
short | 短整数 | 30000 |
常量和类型转换
final double PI = 3.14159; // final 表示常量,不能改
// 类型转换int a = 5;double b = a; // 自动转(小→大)int c = (int) b; // 强制转(大→小,可能丢精度)五、输入:Scanner
Java 用 Scanner 接收用户输入:
import java.util.Scanner; // 引入 Scanner 类
public class Input { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
System.out.print("请输入你的名字:"); String name = scanner.nextLine(); // 读一整行字符串
System.out.print("请输入年龄:"); int age = scanner.nextInt(); // 读整数
System.out.println("你好," + name + ",你今年" + age + "岁"); }}import 是什么? Java 用 import 引入其他类(类似 Python 的 import、JS 的 require),java.util.Scanner 是官方提供的”输入工具类”。
六、条件判断:if / else 和 switch
public class Condition { public static void main(String[] args) { int score = 85;
if (score >= 90) { System.out.println("优秀!"); } else if (score >= 60) { System.out.println("及格"); } else { System.out.println("不及格"); } }}和 C/C++、JS 语法几乎一样。
switch(Java 14+ 新写法更简洁)
int day = 3;switch (day) { case 1 -> System.out.println("周一"); // -> 箭头写法(新版) case 2 -> System.out.println("周二"); case 3 -> System.out.println("周三"); default -> System.out.println("其他");}新版 Java(14+)支持用 -> 代替传统 case: ... break;,代码更简洁。
七、循环:for / while / do-while
public class Loop { public static void main(String[] args) { // for for (int i = 1; i <= 5; i++) { System.out.print(i + " "); } System.out.println(); // 1 2 3 4 5
// while int n = 0; while (n < 3) { System.out.println("第" + n + "次"); n++; }
// 增强 for(遍历数组/集合,最常用) int[] nums = {10, 20, 30}; for (int num : nums) { System.out.print(num + " "); } System.out.println(); // 10 20 30 }}增强 for 是 Java 的特色:for (类型 变量 : 数组/集合) 直接遍历,不用写下标,像 Python 的 for-in。
八、数组
public class Array { public static void main(String[] args) { // 声明数组 int[] scores = {90, 85, 78, 92, 88};
// 访问(下标从 0 开始) System.out.println(scores[0]); // 90
// 修改 scores[2] = 80;
// 长度 System.out.println(scores.length); // 5
// 遍历 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i] + " "); } System.out.println(); }}和 C 的区别: Java 数组会自动检查下标,越界会抛异常(ArrayIndexOutOfBoundsException),不会像 C 那样悄悄出错。
九、字符串 String(Java 特别常用)
public class StringDemo { public static void main(String[] args) { String s = "Hello World";
System.out.println(s.length()); // 11(长度) System.out.println(s.toUpperCase()); // HELLO WORLD System.out.println(s.toLowerCase()); // hello world System.out.println(s.charAt(0)); // H(取第0个字符) System.out.println(s.substring(0, 5)); // Hello(子串)
// 拼接(+ 号) String name = "小明"; System.out.println("你好," + name);
// 比较内容要用 equals,不能用 == String a = "abc"; String b = new String("abc"); System.out.println(a == b); // false(比较的是地址) System.out.println(a.equals(b)); // true(比较的是内容) }}⚠️ 最容易踩的坑: 比较字符串内容必须用 equals(),不能用 ==。因为 == 比较的是内存地址,两个内容相同但地址不同的字符串用 == 会得到 false。
十、面向对象:类和对象
Java 是彻底的面向对象语言,一切围绕类和对象。
定义一个类
public class Student { // 属性(字段) private String name; private int age;
// 构造方法:创建对象时调用 public Student(String name, int age) { this.name = name; this.age = age; }
// 方法 public void introduce() { System.out.println("我叫" + name + ",今年" + age + "岁"); }
// getter public int getAge() { return age; }}使用类(创建对象)
public class Main { public static void main(String[] args) { Student s1 = new Student("小明", 18); // new 创建对象 Student s2 = new Student("小红", 17);
s1.introduce(); // 我叫小明,今年18岁 s2.introduce(); // 我叫小红,今年17岁
System.out.println(s1.getAge()); // 18 }}关键概念:
class:定义”图纸”new:根据图纸”造出”对象this:指”当前这个对象”private/public:访问控制(封装)
三大特性
1. 封装:属性设为 private,通过方法访问(保护数据)
2. 继承:子类继承父类
class Animal { public void eat() { System.out.println("吃东西"); }}
class Dog extends Animal { // extends 继承 public void bark() { System.out.println("汪汪!"); }}
// 使用Dog d = new Dog();d.eat(); // 继承来的d.bark(); // 自己的3. 多态:父类引用指向子类对象
class Animal { public void speak() { System.out.println("动物叫"); }}
class Dog extends Animal { @Override public void speak() { System.out.println("汪汪!"); }}
// 父类引用,子类实现Animal a = new Dog();a.speak(); // 汪汪!(调用的是 Dog 的方法)@Override 注解:告诉编译器”这是覆盖父类的方法”,写错了会报错提醒。
十一、接口 interface
接口定义”规范/能力”,类用 implements 实现它:
// 定义接口interface Flyable { void fly(); // 接口里的方法只有声明,没有实现}
// 类实现接口class Bird implements Flyable { @Override public void fly() { System.out.println("鸟在飞"); }}
class Plane implements Flyable { @Override public void fly() { System.out.println("飞机在飞"); }}
// 使用:都能飞,但实现不同public class Main { public static void main(String[] args) { Flyable[] things = { new Bird(), new Plane() }; for (Flyable f : things) { f.fly(); } }}接口 vs 继承的区别: 一个类只能继承一个父类(单继承),但可以实现多个接口。接口是”能做什么”(能力),继承是”是什么”(血缘)。
十二、异常处理:try / catch
Java 对错误有严格的”异常”机制,程序出错不会崩溃,而是抛出异常让你处理。
public class ExceptionDemo { public static void main(String[] args) { try { int[] nums = {1, 2, 3}; System.out.println(nums[5]); // 越界,会抛异常 } catch (ArrayIndexOutOfBoundsException e) { System.out.println("数组越界了:" + e.getMessage()); } finally { System.out.println("无论对错都会执行(比如关闭资源)"); } }}三种关键字:
try:放可能出错的代码catch:捕获并处理异常finally:无论是否出错都会执行(释放资源用)
自定义异常:
class AgeException extends Exception { public AgeException(String msg) { super(msg); }}
// 使用public static void checkAge(int age) throws AgeException { if (age < 0) { throw new AgeException("年龄不能为负数"); }}十三、集合框架:ArrayList 和 HashMap
Java 的集合类是处理大量数据的主力,比数组灵活(长度可变)。
ArrayList:动态数组
import java.util.ArrayList;
public class ListDemo { public static void main(String[] args) { ArrayList<String> names = new ArrayList<>();
names.add("小明"); // 添加 names.add("小红"); names.add("小刚");
System.out.println(names.size()); // 3(长度) System.out.println(names.get(0)); // 小明(取值) names.set(1, "小红改"); // 修改 names.remove(2); // 删除 names.contains("小明"); // true(是否包含)
// 遍历 for (String n : names) { System.out.println(n); } }}<String> 泛型:告诉集合”里面装的是字符串”,编译时就能检查类型,防止装错。
HashMap:键值对
import java.util.HashMap;
public class MapDemo { public static void main(String[] args) { HashMap<String, Integer> scores = new HashMap<>();
scores.put("小明", 95); // 存 scores.put("小红", 88); scores.put("小刚", 76);
System.out.println(scores.get("小明")); // 95(取) System.out.println(scores.containsKey("小红")); // true
scores.remove("小刚"); // 删
// 遍历键值对 for (String key : scores.keySet()) { System.out.println(key + ":" + scores.get(key)); } }}HashMap 就相当于 JS 里的对象、Go 里的 map——键值对容器,存数据、按 key 查数据。
十四、实战:学生成绩管理系统
把学到的全用上,写一个能录入、查询、统计成绩的小程序:
import java.util.ArrayList;import java.util.Scanner;
public class ScoreManager { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); ArrayList<String> names = new ArrayList<>(); ArrayList<Integer> scores = new ArrayList<>();
while (true) { System.out.println("\n==== 学生成绩管理 ===="); System.out.println("1. 录入成绩"); System.out.println("2. 查看全部"); System.out.println("3. 查看平均分"); System.out.println("4. 退出"); System.out.print("请选择:");
int choice = scanner.nextInt(); scanner.nextLine(); // 吃掉回车
if (choice == 1) { System.out.print("输入姓名:"); String name = scanner.nextLine(); System.out.print("输入成绩:"); int score = scanner.nextInt(); scanner.nextLine(); names.add(name); scores.add(score); System.out.println("已录入!"); } else if (choice == 2) { for (int i = 0; i < names.size(); i++) { System.out.println(names.get(i) + ":" + scores.get(i)); } } else if (choice == 3) { int sum = 0; for (int s : scores) sum += s; double avg = scores.size() > 0 ? (double) sum / scores.size() : 0; System.out.println("平均分:" + avg); } else if (choice == 4) { System.out.println("再见!"); break; } else { System.out.println("输入无效"); } } }}编译运行:
javac ScoreManager.javajava ScoreManager这个程序用到了: Scanner 输入、while 循环、if 分支、ArrayList、for 遍历、break。把每行读懂,你的 Java 基础就扎实了。
练习: 加一个”查找某个学生的成绩”和”显示最高分”功能。
十五、后续该学什么?
学完基础,Java 世界的路线通常是:
- 面向对象加深:接口、内部类、Lambda 表达式、Stream 流
- 常用框架:Spring Boot(后端开发最主流的框架,几乎必学)
- 数据库:JDBC 连数据库,配合 SQL(参考之前的 PGSQL 教程)
- 构建工具:Maven / Gradle(管理依赖和构建)
- 实战项目:做一个 CRUD 的 Web 后端接口
就业角度: Java 后端的主流组合是 Java + Spring Boot + MySQL/PostgreSQL + Redis。先把 Java 基础和面向对象练熟,再进 Spring Boot。
十六、总结
这一篇我们从零学会了 Java:
- Java 是什么:跨平台、面向对象、稳定,跑在 JVM 上
- 装 JDK:javac 编译、java 运行
- Hello World:文件名=类名、固定的 main 方法
- 变量类型:int、double、String、boolean
- 输入:Scanner
- 条件循环:if/switch、for/while、增强 for
- 数组:下标从 0、越界会抛异常
- 字符串:equals 比较内容(坑)、常用方法
- 面向对象:类、对象、封装、继承、多态、接口
- 异常处理:try/catch/finally
- 集合:ArrayList、HashMap
- 实战:学生成绩管理系统
Java 和前面学的 Go、C++ 有很多相通之处(都是强类型、面向对象),你已有的基础会让你学得飞快。多写小项目,把类和集合用熟,你就真正入门 Java 了。