Java核心知识点精讲:从面向对象到函数式编程

一、面向对象编程

1. 类与对象

概念解释
类是对象的蓝图,对象是类的实例。Java中一切皆对象(除了基本数据类型)。

// 类定义
public class Person {
    // 字段(属性)
    private String name;
    private int age;
    
    // 方法
    public void sayHello() {
        System.out.println("Hello, I'm " + name);
    }
}

// 创建对象
Person person = new Person();
person.sayHello();

实践建议

  • 遵循单一职责原则,一个类只做一件事
  • 使用private保护字段,通过getter/setter访问

2. 构造方法与初始化块

public class Order {
    // 静态初始化块(类加载时执行)
    static {
        System.out.println("Static block executed");
    }
    
    // 实例初始化块(每次new时执行)
    {
        System.out.println("Instance block executed");
    }
    
    // 构造方法
    public Order() {
        System.out.println("Constructor executed");
    }
}

执行顺序:静态块 → 实例块 → 构造方法

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. 内部类

// 静态内部类
class Outer {
    static class StaticInner {}
}

// 匿名内部类
Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Anonymous class");
    }
};

使用场景

  • 静态内部类:不需要访问外部类实例时
  • 匿名类:一次性使用的简单实现

二、异常处理

1. 异常体系

图2

最佳实践

  • Error表示严重问题,通常不捕获
  • RuntimeException表示编程错误
  • 检查型异常必须处理

2. try-with-resources

try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    String line = br.readLine();
} catch (IOException e) {
    e.printStackTrace();
}

优势:自动关闭资源,比finally块更简洁

三、集合框架

1. 核心接口关系

图3

2. 常用实现类对比

类型实现类特点
ListArrayList随机访问快,插入删除慢
ListLinkedList插入删除快,随机访问慢
SetHashSet无序,基于哈希表
SetTreeSet有序,基于红黑树
MapHashMap键值对,允许null键值

3. 泛型示例

List<String> list = new ArrayList<>();
list.add("Java");
// list.add(1); // 编译错误

类型擦除:运行时泛型信息被擦除,只保留原始类型

四、多线程与并发

1. 线程创建方式

// 方式1:继承Thread
class MyThread extends Thread {
    public void run() {
        // 线程逻辑
    }
}

// 方式2:实现Runnable
Runnable task = () -> {
    // 线程逻辑
};
new Thread(task).start();

// 方式3:Callable+Future
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
    return 42;
});

2. 线程同步工具

// synchronized方法
public synchronized void increment() {
    count++;
}

// ReentrantLock
Lock lock = new ReentrantLock();
lock.lock();
try {
    // 临界区
} finally {
    lock.unlock();
}

// volatile变量
private volatile boolean flag;

五、I/O与NIO

1. 传统IO示例

// 读取文件
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}

2. NIO核心组件

// 使用Channel和Buffer读取文件
try (FileChannel channel = FileChannel.open(Paths.get("file.txt"))) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (channel.read(buffer) != -1) {
        buffer.flip();
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        buffer.clear();
    }
}

六、反射与注解

1. 反射API示例

Class<?> clazz = Class.forName("com.example.User");
Object obj = clazz.newInstance();

Method method = clazz.getMethod("setName", String.class);
method.invoke(obj, "Alice");

Field field = clazz.getDeclaredField("age");
field.setAccessible(true);
field.set(obj, 25);

2. 自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime {
}

// 使用注解
@LogExecutionTime
public void longRunningMethod() {
    // 方法实现
}

七、函数式编程

1. Lambda表达式

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// 传统方式
Collections.sort(names, new Comparator<String>() {
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

// Lambda方式
Collections.sort(names, (a, b) -> a.compareTo(b));

2. Stream API

List<String> result = names.stream()
    .filter(name -> name.startsWith("A"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

方法引用String::toUpperCase 等价于 s -> s.toUpperCase()


实践总结

  1. 面向对象设计:优先使用组合而非继承,接口优于抽象类
  2. 异常处理:不要吞没异常,记录完整堆栈信息
  3. 集合选择:根据场景选择合适实现,多线程环境考虑并发集合
  4. 并发编程:尽量使用高级并发工具(如ConcurrentHashMap)
  5. IO操作:NIO适合高并发场景,传统IO代码更简单
  6. 反射使用:性能敏感场景避免过度使用反射
  7. 函数式编程:Stream API使集合操作更声明式、更简洁

掌握这些核心知识点,你已经具备了Java开发的中高级能力。建议在实际项目中多实践,遇到问题时深入理解底层原理。

添加新评论