Java核心知识点解析:面向对象到函数式编程
Java核心知识点深度解析:从面向对象到函数式编程
一、面向对象编程
1. 类与对象
概念解释:
类是对象的模板,定义了对象的属性和行为。对象是类的实例,具有具体的状态和行为。
// 类定义
public class Person {
// 属性(成员变量)
private String name;
private int age;
// 方法
public void introduce() {
System.out.println("Hello, I'm " + name);
}
}
// 对象创建
Person person = new Person();
person.introduce();
实践建议:
- 遵循单一职责原则,一个类只负责一个功能
- 使用private保护成员变量,通过getter/setter访问
2. 构造方法与初始化块
public class Order {
// 静态初始化块(类加载时执行)
static {
System.out.println("Static initialization block");
}
// 实例初始化块(每次new时执行)
{
System.out.println("Instance initialization block");
}
// 构造方法
public Order() {
System.out.println("Constructor");
}
}
执行顺序:静态块 → 实例块 → 构造方法
3. 接口与抽象类
classDiagram
class AbstractAnimal {
<<abstract>>
+String name
+abstract void makeSound()
+void sleep()
}
interface Flyable {
<<interface>>
+void fly()
}
class Bird {
+void makeSound()
+void fly()
}
AbstractAnimal <|-- Bird
Flyable <|.. Bird
关键区别:
- 抽象类可以有实现方法,接口在Java 8前只能有抽象方法
- 类只能单继承抽象类,但可实现多个接口
- 接口更适合定义行为契约,抽象类适合代码复用
4. 内部类
public class Outer {
private int x = 10;
// 成员内部类
class Inner {
void accessOuter() {
System.out.println(x); // 可直接访问外部类成员
}
}
// 静态内部类
static class StaticInner {
void show() {
System.out.println("Static inner");
}
}
void method() {
// 局部内部类
class LocalInner {
void display() {
System.out.println("Local inner");
}
}
// 匿名内部类
Runnable r = new Runnable() {
public void run() {
System.out.println("Anonymous inner");
}
};
}
}
使用场景:
- 匿名类:事件监听器、线程实现等一次性使用场景
- 静态内部类:不需要访问外部类实例时,更节省内存
二、异常处理
1. 异常体系
关键类型:
- Error:系统级错误(如OutOfMemoryError),不应捕获
- RuntimeException:未检查异常(如NullPointerException)
- 其他Exception:检查异常,必须处理
2. try-catch-finally
try {
FileInputStream fis = new FileInputStream("file.txt");
// 处理文件
} catch (FileNotFoundException e) {
System.err.println("文件未找到: " + e.getMessage());
} catch (IOException e) {
System.err.println("IO错误: " + e);
} finally {
// 无论是否异常都会执行
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
// 关闭资源时的异常处理
}
}
}
最佳实践:
- 使用try-with-resources简化资源管理
- 不要捕获Exception基类,应捕获具体异常
- finally块中避免return语句
3. 自定义异常
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
super("资金不足,缺少: " + amount);
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
// 使用
void withdraw(double amount) throws InsufficientFundsException {
if (balance < amount) {
throw new InsufficientFundsException(amount - balance);
}
// 其他逻辑
}
三、集合框架
1. 核心接口与实现类
选择指南:
- ArrayList:随机访问多,插入删除少
- LinkedList:频繁插入删除,随机访问少
- HashSet:无序唯一集合,快速查找
- TreeSet:有序唯一集合
- HashMap:键值对存储,快速查找
- LinkedHashMap:保持插入顺序的HashMap
2. 迭代与泛型
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
// 传统迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 增强for循环
for (String lang : list) {
System.out.println(lang);
}
// Java 8 forEach
list.forEach(System.out::println);
类型擦除问题:
List<String> strList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
// 运行时都是List.class
System.out.println(strList.getClass() == intList.getClass()); // true
四、多线程与并发
1. 线程创建方式
// 继承Thread
class MyThread extends Thread {
public void run() {
System.out.println("Thread running");
}
}
// 实现Runnable
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable running");
}
}
// 实现Callable
class MyCallable implements Callable<String> {
public String call() throws Exception {
return "Callable result";
}
}
// 使用
new MyThread().start();
new Thread(new MyRunnable()).start();
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
System.out.println(future.get());
executor.shutdown();
2. 线程同步机制
// synchronized方法
public synchronized void syncMethod() {
// 临界区
}
// synchronized块
public void syncBlock() {
synchronized(this) {
// 临界区
}
}
// ReentrantLock
private final Lock lock = new ReentrantLock();
public void lockMethod() {
lock.lock();
try {
// 临界区
} finally {
lock.unlock();
}
}
// volatile变量
private volatile boolean flag = false;
选择建议:
- synchronized:简单同步场景
- Lock:需要尝试获取锁、超时、公平锁等高级特性
- volatile:保证可见性但不保证原子性
3. 线程池最佳实践
// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100), // 工作队列
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
// 提交任务
executor.execute(() -> System.out.println("Task running"));
Future<String> future = executor.submit(() -> "Result");
// 优雅关闭
executor.shutdown();
try {
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
}
五、I/O与NIO
1. 传统I/O示例
// 字节流复制文件
try (InputStream in = new FileInputStream("source.txt");
OutputStream out = new FileOutputStream("target.txt")) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
// 字符流读取文件
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
2. NIO核心组件
// 文件复制示例
try (FileChannel inChannel = FileChannel.open(Paths.get("source.txt"));
FileChannel outChannel = FileChannel.open(Paths.get("target.txt"),
StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inChannel.read(buffer) != -1) {
buffer.flip(); // 切换为读模式
outChannel.write(buffer);
buffer.clear(); // 清空缓冲区
}
}
// Selector多路复用
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
if (key.isAcceptable()) {
// 处理新连接
} else if (key.isReadable()) {
// 处理读事件
}
iter.remove();
}
}
六、反射与注解
1. 反射API使用
Class<?> clazz = Class.forName("com.example.User");
// 创建实例
Object user = clazz.getDeclaredConstructor().newInstance();
// 访问字段
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true); // 突破private限制
nameField.set(user, "John");
// 调用方法
Method method = clazz.getMethod("setName", String.class);
method.invoke(user, "Alice");
// 获取注解
Annotation[] annotations = clazz.getAnnotations();
2. 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime {
String value() default "";
}
// 使用注解
public class Service {
@LogExecutionTime("processData")
public void processData() {
// 业务逻辑
}
}
// 处理注解
Method method = Service.class.getMethod("processData");
if (method.isAnnotationPresent(LogExecutionTime.class)) {
LogExecutionTime annotation = method.getAnnotation(LogExecutionTime.class);
System.out.println("Method " + annotation.value() + " will be logged");
}
七、函数式编程
1. Lambda表达式
// 替代匿名类
Runnable r = () -> System.out.println("Lambda run");
// 集合排序
List<String> names = Arrays.asList("Bob", "Alice", "Charlie");
names.sort((a, b) -> a.compareTo(b));
// 函数式接口
@FunctionalInterface
interface Calculator {
int calculate(int x, int y);
}
Calculator add = (a, b) -> a + b;
System.out.println(add.calculate(3, 5)); // 8
2. Stream API
List<String> transactions = Arrays.asList("T1001", "T2002", "T1003", "T3004");
// 流操作链
long count = transactions.stream()
.filter(t -> t.startsWith("T1"))
.map(String::toUpperCase)
.sorted()
.peek(System.out::println)
.count();
// 并行流
List<Integer> numbers = IntStream.range(1, 100)
.parallel()
.filter(n -> n % 2 == 0)
.boxed()
.collect(Collectors.toList());
实践建议:
- 避免在lambda中修改外部状态
- 简单操作用stream,复杂业务仍用传统方式
- 大数据量考虑parallelStream,但要注意线程安全
通过本文的系统梳理,我们深入探讨了Java的核心知识点。建议读者结合实际项目需求,选择适合的技术方案,并在实践中不断深化理解。记住,掌握这些基础概念是成为Java专家的必经之路。