Java 作为一门跨平台、面向对象的编程语言,凭借其稳健性、可扩展性和广泛的生态支持,在企业级开发、移动开发等领域占据重要地位。本文将从 Java 基础特性出发,逐步深入核心概念,解析常见面试与开发中的关键问题,助力开发者夯实基础、进阶提升。
干货满满,建议先赞后看,随时回查不迷路。更多开发 学习资料/视频/面试题库 请戳>>Github<< >>gitee<<
一、Java 的核心特性
1. 面向对象编程(OOP)
Java 是纯粹的面向对象编程语言,一切皆围绕 “对象” 展开。面向对象的核心思想是将问题拆解为独立的对象,通过对象间的交互完成功能,相比面向过程更符合现实世界的抽象逻辑。
面向对象 vs 面向过程对比:
- 面向过程:以 “步骤” 为核心,将问题拆解为具体步骤,用函数实现步骤并依次调用。例如五子棋开发,按 “开始游戏→黑子走棋→绘制画面→判断输赢” 的步骤实现。
- 面向对象:以 “对象” 为核心,将问题拆解为 “黑白棋子”“棋盘”“规则” 等对象,通过对象协作完成功能。例如棋盘负责绘制、规则负责判输赢,职责更清晰。
2. 平台独立性与移植性(Write Once, Run Anywhere)
Java 的跨平台特性是其核心优势之一,实现依赖JVM(Java 虚拟机) :
- 开发者编写 Java 源码(.java 文件);
- 通过 javac 编译器将源码编译为字节码文件(.class) ;
- 不同平台(Windows、Linux、Mac)的 JVM 将字节码翻译为本地机器码执行。
由于字节码与平台无关,仅需为不同平台安装对应 JVM,即可实现 “一次编写,到处运行”。

3. 稳健性
Java 的稳健性体现在强类型检查、异常处理等机制:
- 强类型语言:要求变量声明时指定类型,编译期检查类型匹配,避免隐式类型错误;
- 异常处理:通过try/catch/finally捕获并处理运行时异常(如空指针、数组越界),避免程序直接崩溃,提升容错性。
二、JDK、JRE、JVM 的关系
初学者常混淆三者,其实它们是包含与被包含的关系,核心作用各不相同:
| 组件 | 英文全称 | 核心作用 | 包含关系 |
| JVM | Java Virtual Machine | 执行字节码,实现跨平台 | JRE 的核心组成部分 |
| JRE | Java Runtime Environment | Java 程序运行环境 | JVM + Java 核心类库 |
| JDK | Java Development Kit | Java 开发工具包 | JRE + 编译器(javac)+ 调试工具(jdb 等) |
关键结论:
- 仅运行 Java 程序:安装 JRE 即可;
- 开发 Java 程序:需安装 JDK(内置 JRE,无需单独安装)。

三、Java 与 C++ 的核心区别
两者均为面向对象语言,但设计理念与特性差异显著:
| 对比维度 | Java | C++ |
| 面向对象模型 | 纯粹面向对象,所有类继承自Object | 兼容面向过程与面向对象 |
| 跨平台性 | 依赖 JVM 实现跨平台 | 依赖特定平台,编译后为本地机器码 |
| 指针 | 无指针,使用 “安全引用” | 支持指针,灵活性高但易引发内存问题 |
| 内存管理 | 自动垃圾回收(GC) | 手动管理内存(new/delete) |
| 继承 | 单继承,通过接口实现多继承效果 | 支持多继承 |
四、Java 基础核心概念解析
1. 基本数据类型与包装类
Java 数据类型分为基本类型和引用类型,基本类型共 8 种,对应 8 种包装类:
| 基本类型 | 占用空间 | 包装类 | 默认值 |
| boolean | 1bit/4byte | Boolean | false |
| byte | 8bit | Byte | 0 |
| char | 16bit | Character | '\u0000' |
| short | 16bit | Short | 0 |
| int | 32bit | Integer | 0 |
| long | 64bit | Long | 0L |
| float | 32bit | Float | 0.0f |
| double | 64bit | Double | 0.0d |
包装类的核心作用:
- 使基本类型具备对象特性,支持泛型(泛型仅支持引用类型);
- 提供丰富的工具方法(如Integer.parseInt()、Double.valueOf())。
自动装箱与拆箱
Java 5 后支持自动转换,无需手动调用包装类方法:
- 装箱:基本类型→包装类(如int→Integer,底层调用Integer.valueOf());
- 拆箱:包装类→基本类型(如Integer→int,底层调用intValue())。
经典面试题解析:
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true(缓存命中)
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false(缓存未命中)
底层原理:Integer类默认缓存了-128到127之间的对象。当数值在此范围内时,会复用缓存对象;超出该范围则会创建新对象。由于"=="比较的是对象地址,因此会出现不同的结果。
- String核心特性详解
作为Java中最常用的类,String的底层设计有以下几个关键点:
(1)String不可变性的实现原理: 通过源码分析可见:
public final class String
implements Serializable, Comparable<String>, CharSequence {
private final char value[]; // 使用final修饰的字符数组存储数据
private int hash; // 缓存的哈希值
}
- value数组被final修饰,无法指向新数组;
- String 类无对外修改value的方法,因此 String 对象创建后状态不可变。
(2)不可变的优势
- 线程安全:不可变对象可被多线程共享,无需同步;
- 哈希缓存:哈希值固定,作为 Map 键时无需重复计算;
- 安全可靠:URL、密码等敏感信息不可篡改;
- 常量池优化:相同字面量复用常量池对象,节省内存。
(3)String、StringBuffer、StringBuilder 区别
| 特性 | String | StringBuffer | StringBuilder |
| 可变性 | 不可变 | 可变 | 可变 |
| 线程安全 | 安全(不可变) | 安全(synchronized 修饰) | 不安全 |
| 性能 | 低(每次操作新建对象) | 中 | 高(无同步开销) |
建议:单线程场景用StringBuilder,多线程用StringBuffer,避免频繁修改 String。
3. 面向对象四大特性
(1)封装
通过将类属性设置为私有(private),仅通过getter/setter方法提供访问接口,从而降低耦合性。示例:
public class User {
private String name; // 私有属性
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(2)继承
子类可以继承父类的属性和方法,并扩展新的功能。Java采用单继承机制(使用extends关键字):
public class Animal {
public void eat() {
System.out.println("进食");
}
}
public class Dog extends Animal { // 继承Animal类
public void bark() {
System.out.println("汪汪叫"); // 新增方法
}
}
(3)多态
同一行为具有多种表现形式,需满足以下条件:
- 存在继承关系
- 子类重写父类方法
- 父类引用指向子类对象
示例:
Animal animal = new Dog(); // 父类引用指向子类实例
animal.eat(); // 调用子类重写后的方法
(4)抽象
将共性逻辑封装为抽象类或接口,要求子类必须实现具体功能。抽象类使用abstract关键字声明,包含无具体实现的抽象方法:
public abstract class Shape {
public abstract double getArea(); // 抽象方法,需子类实现
}
public class Circle extends Shape {
private double radius;
@Override
public double getArea() {
return Math.PI * radius * radius; // 具体实现抽象方法
}
}
4. 接口与抽象类的区别
| 对比维度 | 抽象类 | 接口 |
| 方法实现 | 可含普通方法和抽象方法 | Java 8 前仅抽象方法,8 后可含默认方法(default) |
| 属性 | 可含任意类型属性 | 仅public static final常量 |
| 继承 / 实现 | 子类用extends继承,单继承 | 类用implements实现,可多实现 |
| 设计理念 | 体现 “is-a” 关系(如 Dog is a Animal) | 体现 “has-a” 关系(如 Dog has a RunAbility) |
五、Java 进阶核心问题
1. 异常处理机制
Java 异常分为Error和Exception:
- Error:JVM 无法解决的严重错误(如StackOverflowError、OutOfMemoryError),程序无法恢复;
- Exception:可处理的异常,分为:
-
- 受检异常(Checked Exception):编译期必须处理(如IOException);
-
- 非受检异常(Unchecked Exception):运行时异常(如NullPointerException、ArrayIndexOutOfBoundsException),无需强制处理。
异常处理语法:
try {
// 可能抛出异常的代码块
} catch (NullPointerException e) {
// 处理空指针异常
e.printStackTrace();
} finally {
// 无论是否发生异常都会执行的代码(通常用于资源清理)
}
2. 反射机制
反射是指在运行时动态获取类的属性、方法,并调用方法的能力。核心 API 包括Class、Constructor、Method、Field。
应用场景:
- 框架开发(如 Spring IOC 容器创建对象);
- 动态代理(如 JDK 动态代理);
- 工具类(如 BeanUtils 属性拷贝)。
示例:通过反射创建对象并调用方法
Class<?> clazz = Class.forName("com.example.User"); // 加载目标类
Object user = clazz.getConstructor().newInstance(); // 通过无参构造函数创建实例
Method setName = clazz.getMethod("setName", String.class); // 获取setName方法
setName.invoke(user, "张三"); // 执行方法设置用户名
3. 泛型
泛型是 Java 5 引入的核心特性,通过在类、接口和方法中定义类型参数,实现更灵活的代码复用。例如:
// 定义泛型类
public class ArrayList<E> {
public boolean add(E e) { ... } // E 表示具体的类型参数
}
// 使用泛型类
ArrayList<String> list = new ArrayList<>();
list.add("Java"); // 只能添加字符串类型元素
泛型的使用让代码更加类型安全,同时减少了强制类型转换的需要。
泛型的优势:
- 编译期类型检查,避免运行时类型转换错误;
- 无需手动类型转换,简化代码。
4. 序列化与反序列化
- 序列化:将对象转换为字节序列(用于持久化或网络传输);
- 反序列化:将字节序列恢复为对象。
实现条件:
- 类实现Serializable接口(标记接口,无具体方法);
- 建议显式声明serialVersionUID(避免类修改后反序列化失败)。
public class User implements Serializable {
// 显式声明序列化版本ID
private static final long serialVersionUID = 1L;
private String name;
private int age;
}
// 对象序列化操作
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.txt"));
oos.writeObject(new User("张三", 20));
// 对象反序列化操作
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.txt"));
User user = (User) ois.readObject();
// 注意事项:
// 1. static修饰的类属性不会参与序列化
// 2. transient修饰的成员变量不会被序列化
5. 并发编程基础
(1)线程创建方式
- 继承Thread类,重写run()方法;
- 实现Runnable接口,重写run()方法;
- 实现Callable接口,重写call()方法(支持返回值和异常抛出)。
(2)线程状态
Java 线程有 6 种状态:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(超时等待)、TERMINATED(终止)。
(3)线程同步
为解决多线程共享资源竞争问题,常用同步方式:
- synchronized关键字(修饰方法或代码块,依赖 JVM 实现);
- ReentrantLock(Java API 实现,支持中断、超时等高级特性)。
六、常见面试题精选
1. 什么是值传递和引用传递?
Java 中只有值传递:
- 基本类型:传递值的副本,修改副本不影响原变量;
- 引用类型:传递引用地址的副本,副本和原引用指向同一对象,修改对象内容会影响原对象,但副本指向新对象不影响原引用。
2. equals () 与 == 的区别?
- ==:
-
- 基本类型:比较值是否相等;
-
- 引用类型:比较对象地址是否相等(是否为同一对象)。
- equals():
-
- 默认(Object 类):同==,比较地址;
-
- 重写后(如 String、Integer):比较对象内容是否相等。
3. 为什么重写 equals () 必须重写 hashCode ()?
根据 Java 规范:
- 若a.equals(b) == true,则a.hashCode() == b.hashCode()必须成立;
- 若不重写hashCode(),可能出现 “equals 相等但 hashCode 不等” 的情况,导致 HashMap 等集合无法正确存储对象。
4. 深拷贝与浅拷贝的区别?
- 浅拷贝:仅拷贝对象本身,引用类型属性仍指向原对象(如Object.clone()默认实现);
- 深拷贝:拷贝对象及所有引用类型属性,两者完全独立(需手动实现,如递归克隆或序列化)。
5. Java 8 的新特性有哪些?
- Lambda 表达式:简化匿名内部类代码(如(a,b)->a+b);
- Stream API:简化集合操作(如过滤、排序、映射);
- 默认方法:接口可含default方法(带实现);
- Optional 类:解决空指针问题;
- 新日期时间 API:java.time包,替代旧的Date和Calendar。
七、总结
Java 知识点体系庞大,本文从基础特性、核心概念到进阶问题进行了系统梳理,涵盖了开发与面试中的高频内容。掌握这些知识点不仅能提升日常开发效率,更能应对面试中的各类问题。建议结合实际项目实践,深入理解底层原理(如 JVM 内存模型、GC 机制),进一步提升 Java 技术栈的深度与广度。


6万+

被折叠的 条评论
为什么被折叠?



