抛出一个问题?
Java 版本的命名约定很令人困惑。有 JDK 1.0,1.2,1.3,1.4,然后跳到 J2SE 5.0,然后变成 Java 6,Java 7,上次我查看时,Java 已经到了 Java 21。发生了什么?
1. JDK 1.0 - 1.4(1996-2002)
最初的 Java 版本采用
JDK 1.x
的命名方式,例如 JDK 1.0(1996)、JDK 1.2(1998)、JDK 1.3(2000)和 JDK 1.4(2002)。此时的版本号以
1.x
形式存在,其中x
是主版本号。2. J2SE 5.0(2004)
重大更名:Sun Microsystems(当时的 Java 所有者)将 Java 平台重命名为J2SE(Java 2 Platform, Standard Edition),并将版本号调整为5.0(跳过了 2.0-4.0)。
这一版本引入了泛型、自动装箱 / 拆箱等重要特性,为简化版本号并突出版本的成熟度,直接使用整数
5.0
作为版本号。3. Java SE 6/7/8(2006-2014)
再次更名:Sun 被 Oracle 收购后,进一步简化命名,去掉了
J2SE
中的2
,改为Java SE(Java Platform, Standard Edition)。版本号直接使用整数,如 Java SE 6(2006)、Java SE 7(2011)、Java SE 8(2014)。
长期支持(LTS)版本:Java 8 是第一个 LTS 版本,提供长达 10 年的支持,至今仍被广泛使用。
4. Java 9 - 17(2017-2021)
版本号简化:从 Java 9 开始,Oracle 采用年度发布周期,每年 3 月和 9 月发布两个版本,版本号直接使用数字(如 Java 9、Java 10 等)。
LTS 版本固定:每三年发布一个 LTS 版本(Java 11、Java 17),提供长期支持;非 LTS 版本仅支持 6 个月。
5. 当前版本(截至 2025 年)
Java 17(LTS):2021 年 9 月发布,是目前的主流 LTS 版本,广泛用于企业级应用。
Java 21(LTS):2023 年 9 月发布,是最新的 LTS 版本,包含了 Record、Pattern Matching 等新特性。
短期版本:Java 18、19、20 等为非 LTS 版本,用于快速迭代新特性。
为什么命名会变?
品牌简化:去掉
J2SE
中的2
和SE
后缀,直接使用Java X
更简洁,便于市场推广。版本号规范化:从
1.x
到整数版本(如 5.0、6、7),再到直接使用数字(9、10、11),使版本号更直观。适应快速发布周期:年度发布周期需要更简单的版本号管理方式,避免复杂的小数点版本。
如何选择版本?
生产环境:建议使用 LTS 版本(Java 8、11、17、21),确保长期稳定性和安全更新。
开发环境:可使用最新的 LTS 版本或非 LTS 版本体验新特性。
1.JVM:Java 的 “跨平台秘密武器”
JVM 就像是一个 “翻译官”,它把 Java 代码(.class 文件)翻译成不同操作系统能听懂的 “方言”。
- 一次编写,到处运行(Write Once, Run Anywhere):就像拍电影 subtitles,全球观众都能看懂。
- 内存管理自动化:JVM 自带 “垃圾回收站”(GC),帮你自动清理不用的内存,再也不用担心内存泄漏!
- 安全性高:JVM 有 “沙箱机制”,就像给代码戴上了 “安全头盔”,防止恶意代码搞破坏。
Java 虚拟机(JVM)包含在 JDK(Java Development Kit)中。JDK 是 Java 开发的核心工具包,它不仅包含 JVM,还提供了编译器(javac)、调试工具、文档工具(javadoc)等开发所需的工具。
而 JRE(Java Runtime Environment)则是 Java 程序的运行环境,它包含 JVM、Java 核心类库以及其他支持文件。JRE 是运行 Java 程序的最小环境。
简单来说,JDK 是面向开发者的,JRE 是面向使用者的。如果你只需要运行 Java 程序,安装 JRE 即可;如果要开发 Java 程序,则需要安装 JDK。
2.面向对象有三大特性:封装、继承和多态。
就好比说我们先来认识一个 “人类” 的类吧。这个人类啊,把他的各种特点都装在了一个小盒子里,这个过程就叫封装。这个盒子里有他的名字(比如叫 “大聪明”)、年龄(假设是 25 岁)、性别(假设是男)这些属性。那他还能干啥呢?能吃饭、能睡觉、能跑步,这些就相当于这个人类类里的方法啦。外人呢,如果想要了解这个人类或者让他干点啥,就得按照我们设定好的方式来操作这个小盒子,不能随意乱动里面的东西呀。
然后说到继承,那就好比人类这个 “爸爸类”,生了个儿子 “学生类”。这个学生呢,就天然继承了人类的各种基本属性,像名字、年龄、性别这些就都有啦,也继承了吃饭、睡觉、跑步这些基本动作。但是他还有自己独特的东西,比如会学习新知识,这就可以在学生类里新增一个学习的方法,这就是在继承的基础上进行了扩展呢。
再看看多态。比如说有个函数,它本来是想让一个人去跑步的。但是如果这时候把一个学生对象(因为学生也是人的一种呀,继承自人类)传进去,那这个学生就可以按照他自己独特的方式去跑步,或者还能在跑步间隙穿插着背几个单词呢,这就是多态啦,一个东西可以有多种表现形态。
// 定义一个动物类
class Animal {
// 属性
String name;
// 构造方法
public Animal(String name) {
this.name = name;
}
// 方法
public void eat() {
System.out.println(name + " 吃东西");
}
}
// 定义一个狗类,继承动物类
class Dog extends Animal {
// 构造方法
public Dog(String name) {
super(name); // 调用父类构造方法
}
// 重写 eat 方法,展示多态
@Override
public void eat() {
System.out.println(name + " 吃狗粮");
}
// 添加狗特有的方法
public void bark() {
System.out.println(name + " 汪汪汪");
}
}
// 测试类
public class Test {
public static void main(String[] args) {
// 创建动物对象
Animal animal = new Animal("小动物");
animal.eat(); // 输出:小动物 吃东西
// 创建狗对象,利用多态
Animal dog = new Dog("旺财");
dog.eat(); // 输出:旺财 吃狗粮,这里体现了多态哦
// Dog dog = (Dog) dogAnimal; 要想调用 bark 方法就得这样先类型转换
// dog.bark();
}
}
3.类与对象:Java 的 “万物皆对象” 哲学
类(Class):是对象的 “模板”,就像造汽车的蓝图。
class Car {
String color; // 颜色属性
int wheels; // 轮子数量
void drive() { // 开车方法
System.out.println("滴滴!");
}
}
对象(Object):是类的 “实例”,就像根据蓝图造出来的具体汽车。
Car myCar = new Car(); // 造一辆车!
myCar.color = "红色"; // 涂色
myCar.wheels = 4; // 装轮子
myCar.drive(); // 开车:滴滴!
4.循环:Java 的 “复读机”
for 循环:适合已知次数的循环,就像 “唱 K 时的副歌部分,重复固定次数”。
for (int i = 0; i < 3; i++) {
System.out.println("Hello World!"); // 重复3次
}
while 循环:适合未知次数的循环,就像 “等外卖,直到外卖送到为止”。
boolean hasFood = false;
while (!hasFood) {
System.out.println("等外卖...");
hasFood = checkDelivery(); // 检查外卖是否送到
}
foreach 循环:遍历集合的 “懒人写法”,就像 “挨个检查超市货架上的商品”。
String[] fruits = {"苹果", "香蕉", "橘子"};
for (String fruit : fruits) {
System.out.println("吃" + fruit); // 逐个吃水果
}
5. 数组:Java 的 “收纳盒”
数组是存放相同类型数据的 “连续盒子”,每个盒子有编号(索引)。
缺点:长度固定,就像买了个 5 格的收纳盒,装满后不能再加格子。
int[] scores = new int[5]; // 创建一个能装5个整数的盒子
scores[0] = 90; // 第1个盒子放90
scores[1] = 85; // 第2个盒子放85
System.out.println(scores[0]); // 输出:90
6.列表(List):Java 的 “弹性收纳盒”
列表是动态扩容的容器,比数组更灵活,就像 “可以无限拉伸的橡皮筋收纳盒”。
import java.util.ArrayList;
import java.util.List;
List<String> names = new ArrayList<>(); // 创建弹性盒子
names.add("张三"); // 添加元素
names.add("李四");
names.add("王五");
System.out.println(names.get(0)); // 输出:张三
System.out.println(names.size()); // 输出:3(当前元素数量)
优势:
- 自动扩容,不用操心长度。
- 支持增删改查,功能比数组强大 100 倍!
7.接口(Interface):Java 的 “合同说明书”
接口是一种 “纯抽象的模板”,只定义方法名,不实现具体逻辑。
作用:
- 强制子类实现某些方法,就像 “签合同必须履行条款”。
- 实现 “多继承” 效果(一个类可以实现多个接口)。
interface Flyable { // 会飞的接口
void fly(); // 只声明方法,不实现
}
class Bird implements Flyable { // 鸟实现飞的接口
@Override
public void fly() {
System.out.println("展翅高飞");
}
}
8.抽象类(Abstract Class):Java 的 “半成品模板”
抽象类是 “介于普通类和接口之间” 的存在,既可以有抽象方法(未实现),也可以有具体方法。
abstract class Shape { // 抽象类
abstract double area(); // 抽象方法(必须由子类实现)
void printType() { // 具体方法
System.out.println("这是一个形状");
}
}
class Circle extends Shape {
double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() { // 实现抽象方法
return Math.PI * radius * radius;
}
}
9.异常处理:Java 的 “代码防弹衣”
Java 用try-catch-finally
处理异常,就像 “给代码穿防弹衣”。
try {
int result = 10 / 0; // 会抛出ArithmeticException
} catch (ArithmeticException e) {
System.out.println("错误:除数不能为0!");
} finally {
System.out.println("无论如何都会执行这里");
}
常见异常:
NullPointerException
(空指针异常):就像 “对着空气开枪”。ArrayIndexOutOfBoundsException
(数组越界):就像 “伸手去够不存在的东西”。
自定义异常:
class AgeException extends Exception { // 自定义异常
public AgeException(String message) {
super(message);
}
}
// 使用自定义异常
void checkAge(int age) throws AgeException {
if (age < 0) {
throw new AgeException("年龄不能为负数!");
}
}
10. 集合框架:Java 的 “数据结构超市”
Java 提供了各种 “容器”,满足不同场景需求。
① List(有序可重复)
ArrayList
:动态数组,适合随机访问。LinkedList
:双向链表,适合频繁插入删除。
② Set(无序不重复)
HashSet
:基于哈希表,快速查找。TreeSet
:基于红黑树,自动排序。
③ Map(键值对)
HashMap
:无序的键值对,快速查找。TreeMap
:按键排序的键值对。
Map<String, Integer> scores = new HashMap<>();
scores.put("张三", 90);
scores.put("李四", 85);
System.out.println(scores.get("张三")); // 输出:90
11. 泛型:Java 的 “类型安全包装器”
泛型让容器只存储特定类型的数据,就像 “给快递盒贴上标签,只装指定类型的东西”。
List<String> names = new ArrayList<>(); // 指定只能装String
names.add("张三");
// names.add(123); // 报错!不能添加Integer类型
12.枚举(Enum):Java 的 “选项卡”
枚举用于定义固定的常量集合,就像 “手机的网络模式:2G/3G/4G/5G”。
enum Weekday {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Weekday today = Weekday.MONDAY;
if (today == Weekday.SATURDAY || today == Weekday.SUNDAY) {
System.out.println("周末休息!");
} else {
System.out.println("上班ing...");
}
补充:
C++ vs Java:细节差异对照表
概念 | Java | C++ |
---|---|---|
多态 | 默认虚函数,无需关键字 | 需要手动声明virtual |
多重继承 | 不支持(通过接口实现) | 直接支持,但需处理菱形继承 |
接口 | interface 关键字 | 纯抽象类(全纯虚函数) |
异常处理 | 必须声明抛出异常(throws ) | 无需声明,但可使用noexcept |
泛型 | 类型擦除(运行时无类型信息) | 模板(编译时生成具体代码) |
内存管理 | 自动 GC | 手动管理(或智能指针) |
总结:C++ 的 “硬核工具箱”
C++ 和 Java 的核心概念类似,但 C++ 更接近底层,语法更灵活(也更危险):
- 继承与多态:C++ 需要手动管理虚函数,支持多重继承。
- 异常处理:语法类似,但更依赖程序员的自觉性。
- STL 容器:功能强大,但需要注意内存管理。
- 模板:比 Java 泛型更灵活,但可能导致编译时间变长。