1. Java学习笔记1.14:从基础到实战的完整指南
作为一名有十年Java开发经验的工程师,我经常被问到如何系统性地学习Java。今天这份笔记不同于普通的语法罗列,而是结合我踩过的坑和项目经验,整理出的实战向学习路径。无论你是刚接触编程的大学生,还是想转行Java的职场人,这份笔记都能帮你避开弯路,直击核心。
Java作为一门经久不衰的编程语言,在企业级开发、安卓应用、大数据处理等领域占据着不可替代的位置。但很多初学者容易陷入两个误区:要么死记硬背语法细节,要么过早接触框架而忽视基础。这份1.14版本的笔记特别强化了面向对象思想、集合框架和多线程这三个Java工程师日常最常用的核心技能,并附带了可运行的代码示例和调试技巧。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Java环境配置与开发工具选择
2.1 JDK版本选择与安装
当前主流使用的是JDK 11(LTS版本)和JDK 17(最新LTS),对于初学者我推荐JDK 11,因为它的稳定性和兼容性已经过充分验证。安装时注意:
- 从Oracle官网或AdoptOpenJDK下载对应操作系统的安装包
- 设置JAVA_HOME环境变量(Windows在系统属性中设置,Mac/Linux在~/.bash_profile中添加)
- 验证安装:在终端运行
java -version和javac -version
注意:避免同时安装多个JDK版本,容易导致环境混乱。如果必须多版本共存,可以使用jenv或手动切换JAVA_HOME。
2.2 IDE的选择与配置
IntelliJ IDEA社区版对初学者完全够用,比Eclipse有更智能的代码提示和重构功能。首次使用时建议:
- 调整字体和主题(Settings -> Editor -> Font)
- 安装关键插件:Key Promoter X(快捷键提示)、Rainbow Brackets(彩色括号)
- 配置代码模板(Settings -> Editor -> Live Templates)
java复制// 示例:快速生成main方法的模板
public class Main {
public static void main(String[] args) {
// 输入'sout'按Tab键会自动补全为System.out.println();
}
}
3. Java核心语法精要
3.1 面向对象编程的三大特性
封装、继承、多态不是抽象概念,而是解决实际问题的工具。以电商系统为例:
java复制// 封装示例:隐藏内部实现细节
public class Product {
private double price; // 私有字段
// 公开方法控制访问
public void setPrice(double newPrice) {
if(newPrice > 0) {
this.price = newPrice;
}
}
}
// 继承示例:代码复用
public class ElectronicProduct extends Product {
private int warrantyMonths;
}
// 多态示例:同一接口不同实现
public interface Payment {
void pay(double amount);
}
public class CreditCardPayment implements Payment {
@Override
public void pay(double amount) { /* 信用卡支付逻辑 */ }
}
3.2 集合框架实战技巧
ArrayList和LinkedList的选择不是靠死记,而是理解底层原理:
- ArrayList:基于动态数组,随机访问快(O(1)),但中间插入/删除慢(需要移动元素)
- LinkedList:基于双向链表,插入删除快(O(1)),但随机访问慢(需要遍历)
java复制// 正确遍历并删除元素的方式
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
Iterator<String> it = list.iterator();
while(it.hasNext()) {
if(it.next().equals("B")) {
it.remove(); // 使用迭代器安全删除
}
}
踩坑提醒:不要在foreach循环中直接调用list.remove(),会抛出ConcurrentModificationException
4. 异常处理与调试技巧
4.1 异常处理最佳实践
Java的异常分为Checked Exception和Unchecked Exception。处理原则:
- 对可恢复情况使用Checked Exception(如文件未找到)
- 对编程错误使用Unchecked Exception(如空指针)
- 不要捕获异常后什么都不做(空的catch块)
- 优先使用try-with-resources管理资源
java复制// 好的异常处理示例
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.err.println("文件未找到,请检查路径: " + e.getMessage());
} catch (IOException e) {
System.err.println("IO错误: " + e.getMessage());
}
4.2 使用断点调试的进阶技巧
- 条件断点:右键点击断点 -> 设置条件(如
i > 5) - 异常断点:Run -> View Breakpoints -> 勾选Java Exception Breakpoints
- 表达式求值:在Debug模式下选中变量或表达式,按Alt+F8
- 多线程调试:在断点上右键选择Suspend为Thread而非All
5. 多线程编程核心要点
5.1 创建线程的三种方式
- 继承Thread类(不推荐,Java不支持多重继承)
- 实现Runnable接口(更灵活)
- 使用Callable和Future(可以获取返回值)
java复制// 使用线程池的正确方式
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<Integer> future = executor.submit(() -> {
TimeUnit.SECONDS.sleep(1);
return 42;
});
// 获取结果(会阻塞直到计算完成)
int result = future.get();
executor.shutdown();
5.2 线程安全与锁优化
synchronized关键字是最基本的同步手段,但在高并发场景下要考虑:
- 减小同步代码块范围
- 使用ReentrantLock的可中断、超时特性
- 读写分离场景用ReadWriteLock
- 原子变量类(AtomicInteger等)的无锁编程
java复制// 使用ConcurrentHashMap替代同步的HashMap
Map<String, Integer> map = new ConcurrentHashMap<>();
map.compute("key", (k, v) -> v == null ? 1 : v + 1);
6. Java 8新特性实战
6.1 Lambda表达式与Stream API
Lambda不是语法糖,而是行为参数化的实现方式。结合Stream API可以写出更声明式的代码:
java复制List<Product> products = /* 获取产品列表 */;
// 传统方式
List<Product> filtered = new ArrayList<>();
for(Product p : products) {
if(p.getPrice() > 100) {
filtered.add(p);
}
}
Collections.sort(filtered, Comparator.comparing(Product::getName));
// Java 8方式
List<Product> filtered = products.stream()
.filter(p -> p.getPrice() > 100)
.sorted(Comparator.comparing(Product::getName))
.collect(Collectors.toList());
6.2 Optional避免空指针
不要用Optional取代所有null检查,它的正确使用场景是:
- 明确表示返回值可能为空的场景
- 避免多层null检查嵌套
- 与Stream API结合使用
java复制// 不好的用法
Optional<User> user = Optional.of(getUser()); // 如果getUser()可能返回null,应该用ofNullable
// 好的用法
String city = getUser()
.flatMap(User::getAddress)
.map(Address::getCity)
.orElse("未知城市");
7. 常见问题排查手册
7.1 ClassNotFoundException vs NoClassDefFoundError
- ClassNotFoundException:类加载器在运行时找不到类(检查classpath)
- NoClassDefFoundError:编译时存在但运行时找不到(通常是静态初始化失败)
7.2 内存泄漏场景识别
- 静态集合持有对象引用
- 未关闭的资源(数据库连接、文件流)
- 监听器未注销
- 使用ThreadLocal后未remove
使用VisualVM或MAT工具分析heap dump可以定位泄漏点。
7.3 性能优化小技巧
- 字符串拼接用StringBuilder
- 频繁调用的方法考虑内联(小方法)
- 集合初始化指定容量
- 使用基本类型而非包装类(如int而非Integer)
java复制// 不好的写法
String result = "";
for(int i=0; i<100; i++) {
result += i; // 每次循环创建新的StringBuilder和String对象
}
// 好的写法
StringBuilder sb = new StringBuilder(100);
for(int i=0; i<100; i++) {
sb.append(i);
}
String result = sb.toString();
8. 学习资源与进阶路线
8.1 推荐书籍
- 入门:《Head First Java》(图文并茂)
- 进阶:《Effective Java》(最佳实践)
- 深入:《Java并发编程实战》
8.2 实战项目建议
- 个人博客系统(Servlet/JSP)
- 电商购物车(Spring Boot)
- 即时通讯工具(Netty)
- 数据分析平台(Spark)
8.3 面试准备重点
- JVM内存模型
- HashMap实现原理
- 线程池参数配置
- Spring循环依赖解决
我在带新人时最常强调的一点是:不要满足于能运行代码,要理解每个API背后的设计意图。比如为什么ArrayList的默认初始容量是10?为什么String要设计为不可变?这些思考能帮你真正掌握Java的精髓。
