1. Java基础核心概念回顾
Java作为一门面向对象的编程语言,其基础概念构成了整个技术体系的根基。在Java基础部分,数据类型、运算符和控制结构是最核心的三大支柱。
1.1 数据类型系统详解
Java的数据类型分为两大类:基本数据类型和引用数据类型。基本数据类型包括byte(1字节)、short(2字节)、int(4字节)、long(8字节)、float(4字节)、double(8字节)、char(2字节)和boolean(JVM规范未明确规定大小,通常为1字节)。这些类型在内存中的存储方式直接影响程序性能。
引用数据类型则包含类、接口、数组等。与基本类型不同,引用类型变量存储的是对象的引用(内存地址),而非对象本身。例如:
String str = "Hello"; // str是引用变量
int[] arr = new int[10]; // arr是数组引用
注意:Java中所有基本数据类型都有对应的包装类(如Integer对应int),自动装箱和拆箱机制使得它们可以互相转换,但要注意可能引发的NullPointerException。
1.2 运算符的深层原理
Java运算符可分为算术运算符(+、-、*、/、%)、关系运算符(>、<、==等)、逻辑运算符(&&、||、!)、位运算符(&、|、^、~、<<、>>、>>>)等。其中几个易错点:
-
除法运算符
/:当两个整数相除时,结果会自动截断小数部分。例如5/2结果是2而非2.5 -
取模运算符
%:结果符号与被除数相同。-7%3得-1,而7%-3得1 -
位运算符:在处理二进制数据时效率极高,但要注意移位运算符的区别:
-
<<左移:低位补0 -
>>右移:高位补符号位 -
>>>无符号右移:高位补0
-
1.3 控制结构的工程实践
控制结构决定了程序执行的流程,主要包括条件语句和循环语句。
if-else语句 的优化写法:
// 常规写法
if(condition) {
// code block
} else {
// else block
}
// 更优写法:提前返回减少嵌套
if(!condition) {
// else block
return;
}
// code block
switch语句 在Java 12后支持箭头表达式和返回值:
String result = switch(day) {
case "MON", "TUE" -> "工作日";
case "SAT", "SUN" -> {
System.out.println("周末");
yield "休息日";
}
default -> "未知";
};
循环结构 的选择策略:
- 已知循环次数:for循环
- 未知次数但需要先判断条件:while循环
- 至少执行一次:do-while循环
- 遍历集合:增强for循环或迭代器
2. 面向对象编程精要
面向对象是Java的核心范式,理解其三大特性(封装、继承、多态)是编写高质量Java代码的基础。
2.1 类与对象的本质
类是对象的模板,定义了属性和方法。对象是类的实例,存储在堆内存中。构造方法是创建对象的特殊方法,如果没有显式定义,编译器会提供默认无参构造方法。
public class Person {
private String name; // 字段封装
private int age;
// 构造方法重载
public Person() {}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 方法
public void introduce() {
System.out.println("I'm " + name + ", " + age + " years old.");
}
}
实际开发中,建议遵循以下原则:
- 字段尽量私有化(private)
- 通过getter/setter方法访问字段
- 构造方法不宜过多,必要时使用Builder模式
2.2 继承与多态的实现机制
继承通过
extends
关键字实现,子类可以获得父类的非私有属性和方法。Java是单继承语言,一个类只能直接继承一个父类。
class Employee extends Person {
private String department;
@Override // 方法重写
public void introduce() {
super.introduce(); // 调用父类方法
System.out.println("I work in " + department);
}
}
多态的实现依赖于方法重写和向上转型:
Person p = new Employee(); // 向上转型
p.introduce(); // 实际调用的是Employee的introduce方法
2.3 接口与抽象类的工程选择
接口(interface)定义行为规范,Java 8后接口可以包含默认方法和静态方法。抽象类(abstract class)则用于部分实现的类模板。
选择策略:
- 需要定义行为规范而不关心实现:用接口
- 需要提供部分公共实现:用抽象类
- 需要多重继承:只能通过接口实现
- Java 8以后,接口和抽象类的界限变得模糊,需根据具体场景决定
interface Flyable {
void fly(); // 抽象方法
default void land() { // 默认方法
System.out.println("Landing...");
}
}
abstract class Bird {
public abstract void sing(); // 抽象方法
public void eat() { // 具体方法
System.out.println("Eating...");
}
}
3. 异常处理与调试技巧
健壮的Java程序必须妥善处理异常,理解异常机制能有效提升代码质量。
3.1 Java异常体系解析
Java异常分为检查型异常(Checked Exception)和非检查型异常(Unchecked Exception)。所有异常都继承自Throwable类:
Throwable
├── Error (非检查型,如OutOfMemoryError)
└── Exception
├── RuntimeException (非检查型,如NullPointerException)
└── 其他Exception (检查型,如IOException)
处理异常的最佳实践:
- 不要捕获Throwable或Error,这些通常是无法恢复的严重问题
- 检查型异常必须处理(捕获或声明抛出)
- 非检查型异常通常由编程错误引起,应修复代码而非捕获
3.2 try-with-resources模式
Java 7引入的try-with-resources语句可自动关闭实现了AutoCloseable接口的资源,比传统的try-catch-finally更简洁安全:
try (InputStream is = new FileInputStream("test.txt");
OutputStream os = new FileOutputStream("output.txt")) {
// 使用资源
} catch (IOException e) {
e.printStackTrace();
}
// 无需手动关闭,自动调用close()
3.3 调试与日志记录技巧
使用断言(assert)进行调试:
assert x > 0 : "x must be positive"; // 需启用-ea参数
日志记录推荐使用SLF4J+Logback组合:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClass {
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
public void doSomething() {
logger.debug("Debug message");
logger.info("Operation completed");
logger.error("Error occurred", exception);
}
}
提示:在复杂的业务系统中,合理的日志级别设置和格式规范能极大提升问题排查效率。建议遵循以下原则:
- ERROR:需要立即处理的严重问题
- WARN:潜在问题或异常情况
- INFO:重要的业务流程节点
- DEBUG:调试信息
- TRACE:最详细的跟踪信息
4. 集合框架与泛型应用
Java集合框架提供了一套性能优良、使用方便的接口和类,位于java.util包中。
4.1 核心集合接口对比
主要接口包括:
-
Collection:所有集合类的根接口
- List:有序可重复(ArrayList、LinkedList)
- Set:无序唯一(HashSet、TreeSet)
- Queue:队列(LinkedList、PriorityQueue)
- Map:键值对(HashMap、TreeMap)
选择集合类的考量因素:
- 是否需要保持元素顺序
- 是否需要快速随机访问
- 是否需要元素唯一性
- 插入和删除操作的频率
4.2 ArrayList与LinkedList的底层实现
ArrayList :
- 基于动态数组实现
- 随机访问快(O(1))
- 插入删除慢(平均O(n))
- 默认初始容量10,扩容系数1.5
LinkedList :
- 基于双向链表实现
- 随机访问慢(O(n))
- 插入删除快(O(1))
- 每个元素需要额外存储前后节点引用
4.3 泛型的高级应用
泛型提供了编译时类型安全检查,避免了运行时的ClassCastException。通配符使用:
// 上界通配符:接受Number及其子类
List<? extends Number> list1 = new ArrayList<Integer>();
// 下界通配符:接受Integer及其父类
List<? super Integer> list2 = new ArrayList<Number>();
// 类型擦除后的桥方法示例
class MyClass<T> {
T value;
void set(T val) { this.value = val; }
T get() { return value; }
}
// 编译后会生成两个方法:
// void set(Object val)
// Object get()
5. Java新特性与编码实践
Java的持续更新带来了许多提升开发效率的新特性。
5.1 Java 8核心特性
Lambda表达式 :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.sort((a, b) -> a.compareTo(b)); // Lambda表达式
Stream API :
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.mapToInt(n -> n * 2)
.sum();
Optional类 :
Optional<String> optional = Optional.ofNullable(getName());
String result = optional.orElse("default");
5.2 Java模块系统(Java 9+)
module-info.java示例:
module com.myapp {
requires java.base; // 隐式依赖
requires java.sql;
requires transitive com.common; // 传递依赖
exports com.myapp.api;
opens com.myapp.internal to com.test;
}
5.3 记录类(Java 14+)和模式匹配(Java 16+)
记录类简化了不可变类的定义:
public record Point(int x, int y) {
// 自动生成构造方法、equals、hashCode、toString等
}
模式匹配instanceof:
if (obj instanceof String s) {
System.out.println(s.length()); // 直接使用s
}
6. 性能优化与内存管理
理解JVM内存模型和垃圾回收机制对编写高性能Java程序至关重要。
6.1 JVM内存结构
- 方法区:存储类信息、常量、静态变量等
-
堆:对象实例存储区域,GC主要工作区
- 新生代(Eden、Survivor0、Survivor1)
- 老年代
- 虚拟机栈:线程私有,存储栈帧(局部变量表、操作数栈等)
- 本地方法栈:为Native方法服务
- 程序计数器:线程私有,指示当前线程执行位置
6.2 常见GC算法
- 标记-清除:简单但产生内存碎片
- 复制算法:高效但浪费空间
- 标记-整理:适合老年代
- 分代收集:结合多种算法,现代JVM主流策略
6.3 性能优化技巧
- 对象复用:使用对象池(如数据库连接池)
- 减少临时对象:避免在循环中创建对象
- 选择合适的集合:根据场景选择ArrayList或LinkedList
- 使用StringBuilder代替字符串拼接
-
合理设置JVM参数:
- -Xms和-Xmx设置堆初始和最大大小
- -XX:NewRatio设置新生代与老年代比例
- -XX:SurvivorRatio设置Eden与Survivor区比例
// 不推荐的写法:每次循环都创建新StringBuilder
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
sb.append("Item ").append(i);
System.out.println(sb.toString());
}
// 推荐的写法:复用StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.setLength(0); // 清空内容
sb.append("Item ").append(i);
System.out.println(sb.toString());
}
7. 多线程与并发编程
Java提供了丰富的API支持多线程开发,但并发编程也带来了新的挑战。
7.1 线程创建方式
- 继承Thread类:
class MyThread extends Thread {
public void run() {
System.out.println("Thread running");
}
}
new MyThread().start();
- 实现Runnable接口:
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable running");
}
}
new Thread(new MyRunnable()).start();
- 实现Callable接口(可返回结果):
class MyCallable implements Callable<String> {
public String call() throws Exception {
return "Callable result";
}
}
FutureTask<String> task = new FutureTask<>(new MyCallable());
new Thread(task).start();
String result = task.get(); // 获取返回值
7.2 线程池最佳实践
Java通过Executor框架提供线程池支持,常见线程池类型:
- newFixedThreadPool:固定大小线程池
- newCachedThreadPool:可扩容线程池
- newSingleThreadExecutor:单线程池
- newScheduledThreadPool:定时任务线程池
推荐使用ThreadPoolExecutor自定义线程池:
int corePoolSize = 5;
int maxPoolSize = 10;
long keepAliveTime = 60L;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ExecutorService executor = new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
keepAliveTime,
TimeUnit.SECONDS,
workQueue,
threadFactory,
handler
);
7.3 并发工具类应用
CountDownLatch :等待多个线程完成
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 执行任务
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("All threads completed");
CyclicBarrier :线程到达屏障时被阻塞
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("All threads reached barrier");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 执行第一阶段任务
barrier.await();
// 执行第二阶段任务
}).start();
}
Semaphore :控制同时访问的线程数
Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
semaphore.acquire();
// 访问共享资源
} finally {
semaphore.release();
}
}).start();
}
8. I/O与NIO编程
Java提供了多种I/O处理方式,理解它们的区别和适用场景很重要。
8.1 传统I/O流体系
Java I/O流主要分为:
- 字节流:InputStream/OutputStream
- 字符流:Reader/Writer
- 缓冲流:BufferedInputStream/BufferedReader等
- 数据流:DataInputStream/DataOutputStream
- 对象流:ObjectInputStream/ObjectOutputStream
文件复制示例:
try (InputStream is = new FileInputStream("source.txt");
OutputStream os = new FileOutputStream("target.txt")) {
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
}
8.2 NIO核心组件
Java NIO(New I/O)引入了新的I/O模型:
- Channel:类似于流,但可以双向读写
- Buffer:数据容器
- Selector:多路复用器
文件NIO复制示例:
try (FileChannel src = FileChannel.open(Paths.get("source.txt"));
FileChannel dest = FileChannel.open(Paths.get("target.txt"),
StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
src.transferTo(0, src.size(), dest);
}
8.3 网络编程实践
传统Socket编程 :
// 服务端
ServerSocket server = new ServerSocket(8080);
Socket client = server.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(client.getInputStream()));
String request = in.readLine();
// 客户端
Socket socket = new Socket("localhost", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello Server");
NIO非阻塞编程 :
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress(8080));
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
for (SelectionKey key : keys) {
if (key.isAcceptable()) {
// 处理连接
} else if (key.isReadable()) {
// 处理读
}
}
keys.clear();
}
9. 常用工具类与API
Java标准库提供了丰富的工具类,合理使用能提升开发效率。
9.1 日期时间API(Java 8+)
新的java.time包解决了旧Date类的诸多问题:
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dateTime.format(formatter);
Duration duration = Duration.between(startTime, endTime);
Period period = Period.between(startDate, endDate);
9.2 正则表达式应用
Pattern和Matcher类提供正则支持:
Pattern pattern = Pattern.compile("\\d{3}-\\d{2}-\\d{4}");
Matcher matcher = pattern.matcher("123-45-6789");
boolean matches = matcher.matches();
// 分组提取
Pattern emailPattern = Pattern.compile("(\\w+)@(\\w+\\.\\w+)");
Matcher emailMatcher = emailPattern.matcher("user@example.com");
if (emailMatcher.find()) {
String username = emailMatcher.group(1);
String domain = emailMatcher.group(2);
}
9.3 实用工具类
Arrays :
int[] arr = {3, 1, 4, 1, 5};
Arrays.sort(arr);
int index = Arrays.binarySearch(arr, 4);
int[] copy = Arrays.copyOf(arr, 3);
Collections :
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c");
Collections.sort(list);
Collections.reverse(list);
Collections.shuffle(list);
Objects :
String str = null;
Objects.requireNonNull(str, "参数不能为null"); // 抛出NullPointerException
boolean equal = Objects.equals(obj1, obj2);
int hash = Objects.hash(field1, field2, field3);
10. 编码规范与工程实践
良好的编码习惯和工程规范对团队协作和项目维护至关重要。
10.1 命名规范
-
类名:大驼峰,如
CustomerService -
方法名:小驼峰,如
calculateTotalPrice -
常量:全大写加下划线,如
MAX_CONNECTIONS -
包名:全小写,反向域名,如
com.example.project -
布尔变量:以is/has/can等开头,如
isValid
10.2 代码组织原则
- 单一职责原则:每个类/方法只做一件事
- 开闭原则:对扩展开放,对修改关闭
- DRY原则:不要重复自己
- 高内聚低耦合:模块内部紧密相关,模块间依赖最少
10.3 单元测试实践
JUnit 5测试示例:
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
@DisplayName("加法测试")
void testAdd() {
assertEquals(5, calculator.add(2, 3));
}
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void testSquare(int input) {
assertEquals(input * input, calculator.square(input));
}
}
10.4 构建工具与依赖管理
Maven项目结构:
project
├── src
│ ├── main
│ │ ├── java # 源代码
│ │ └── resources # 资源文件
│ └── test
│ ├── java # 测试代码
│ └── resources # 测试资源
├── target # 构建输出
└── pom.xml # 项目配置
pom.xml关键配置:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
11. 设计模式实战应用
设计模式是解决特定问题的经验总结,Java中常用的模式包括:
11.1 单例模式实现
双重检查锁定实现:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
枚举实现(推荐):
public enum Singleton {
INSTANCE;
public void doSomething() {
// 方法实现
}
}
11.2 工厂模式应用
简单工厂:
class ShapeFactory {
public Shape createShape(String type) {
switch (type) {
case "circle": return new Circle();
case "rectangle": return new Rectangle();
default: throw new IllegalArgumentException("Unknown shape");
}
}
}
抽象工厂:
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
class WinFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
public Checkbox createCheckbox() { return new WinCheckbox(); }
}
class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public Checkbox createCheckbox() { return new MacCheckbox(); }
}
11.3 观察者模式实现
Java内置Observable类(已过时,不推荐):
class Subject extends Observable {
private String state;
public void setState(String state) {
this.state = state;
setChanged();
notifyObservers(state);
}
}
class Observer implements java.util.Observer {
public void update(Observable o, Object arg) {
System.out.println("State changed to: " + arg);
}
}
Java 9+推荐使用PropertyChangeListener或自定义实现:
interface Observer {
void update(String message);
}
class ConcreteObserver implements Observer {
public void update(String message) {
System.out.println("Received: " + message);
}
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) {
observers.add(o);
}
public void notifyObservers(String message) {
for (Observer o : observers) {
o.update(message);
}
}
}
12. Java生态与进阶方向
掌握Java基础后,可以根据兴趣选择不同的发展方向。
12.1 主流Java框架
-
Spring框架 :企业级应用开发
- Spring Core:IoC容器
- Spring MVC:Web框架
- Spring Boot:快速开发
- Spring Data:数据访问
- Spring Security:安全控制
-
Hibernate :ORM框架
-
MyBatis :SQL映射框架
-
Jakarta EE :企业版Java规范
12.2 微服务架构
Spring Cloud组件:
- Eureka:服务注册与发现
- Ribbon:客户端负载均衡
- Feign:声明式REST客户端
- Hystrix:熔断器
- Zuul:API网关
- Config:分布式配置
- Sleuth:分布式追踪
12.3 性能调优工具
- JVisualVM :可视化监控
- JConsole :JMX监控
- Java Mission Control :商业级监控
- Arthas :阿里开源的Java诊断工具
- JMH :Java微基准测试工具
12.4 学习资源推荐
- 官方文档:Oracle Java Docs
-
书籍:
- 《Java核心技术》
- 《Effective Java》
- 《Java并发编程实战》
- 《深入理解Java虚拟机》
- 在线课程:Coursera、Udemy、慕课网
- 社区:Stack Overflow、GitHub、掘金
在实际项目开发中,我发现很多初学者容易忽视基础知识的深度理解,而直接跳入框架学习。这种做法虽然能快速上手简单项目,但当遇到复杂问题时往往难以有效解决。建议在学习任何框架前,先扎实掌握Java核心概念和设计模式,这样在接触新框架时能够更快理解其设计思想和工作原理。



1018

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



