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 blockswitch语句在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核心概念和设计模式,这样在接触新框架时能够更快理解其设计思想和工作原理。