Java 高级特性深入解析
一、泛型(Generics)
1. 泛型的基本概念
泛型是 JDK 5 引入的特性,本质是参数化类型,允许在定义类、接口和方法时使用类型参数,在使用时再指定具体类型。
2. 泛型的核心优势
- 编译时类型安全:在编译阶段就能捕获类型错误,避免运行时出现 ClassCastException
- 消除强制类型转换:使用泛型后无需手动进行类型转换,提高代码可读性
- 代码重用性:一套代码可以处理多种类型的数据
3. 泛型的使用形式
(1) 泛型类
java
public class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
// 使用泛型类
Box<String> stringBox = new Box<>();
stringBox.setValue("Hello"); // 只能设置String类型
String result = stringBox.getValue(); // 无需类型转换
(2) 泛型接口
java
public interface List<T> {
void add(T element);
T get(int index);
}
(3) 泛型方法
java
public <T> T getFirstElement(List<T> list) {
if (list != null && !list.isEmpty()) {
return list.get(0);
}
return null;
}
4. 泛型通配符
- 无界通配符
<?>:表示任意类型 - 上界通配符
<? extends T>:表示 T 类型或其子类 - 下界通配符
<? super T>:表示 T 类型或其父类
5. 泛型擦除
泛型信息只存在于编译阶段,在编译后生成的字节码中,泛型相关信息会被擦除:
- 无限制泛型(如
T、?)会被替换为Object - 有上界的泛型(如
T extends Person)会被替换为上界类型
二、反射机制(Reflection)
1. 反射的基本概念
反射是 Java 提供的一种能够在运行时检查、获取和修改类的结构(属性、方法、构造器等)的机制。
2. 反射的核心类
- Class:代表一个类,是反射的入口
- Field:代表类的成员变量
- Method:代表类的方法
- Constructor:代表类的构造器
- Modifier:提供了获取修饰符信息的方法
3. 反射的基本操作
java
// 1. 获取Class对象
Class<?> clazz = Class.forName("com.example.User");
// 或
Class<?> clazz = User.class;
// 或
Class<?> clazz = new User().getClass();
// 2. 创建对象
Object instance = clazz.getDeclaredConstructor().newInstance();
// 3. 获取方法并调用
Method method = clazz.getMethod("setName", String.class);
method.invoke(instance, "张三");
// 4. 获取属性并修改
Field field = clazz.getDeclaredField("age");
field.setAccessible(true); // 设置可访问私有属性
field.set(instance, 25);
4. 反射的应用场景
- 框架开发(如 Spring、Hibernate 等)
- 动态代理
- 序列化和反序列化
- 测试工具
三、注解(Annotation)
1. 注解的基本概念
注解是 JDK 5 引入的一种特殊标记,可以附加在类、方法、变量等元素上,用于为这些元素提供元数据信息。
2. 内置注解
- @Override:标记方法重写
- @Deprecated:标记已过时的元素
- @SuppressWarnings:抑制编译器警告
- @FunctionalInterface:标记函数式接口
3. 元注解
- @Retention :指定注解的保留策略
- RetentionPolicy.SOURCE:源码级别,编译时丢弃
- RetentionPolicy.CLASS:字节码级别,类加载时丢弃
- RetentionPolicy.RUNTIME:运行时级别,可通过反射获取
- @Target:指定注解可应用的元素类型
- @Documented:标记注解将包含在 Javadoc 中
- @Inherited:标记注解可被子类继承
- @Repeatable:标记注解可重复使用
4. 自定义注解
java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value() default "";
int count() default 0;
}
// 使用自定义注解
public class Test {
@MyAnnotation(value = "测试", count = 3)
public void testMethod() {
// 方法体
}
}
5. 注解处理器
通过反射获取和处理注解信息:
java
public void processAnnotations(Class<?> clazz) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
String value = annotation.value();
int count = annotation.count();
// 处理注解信息
}
}
}
四、多线程与并发编程
1. 线程生命周期
Java 线程的生命周期包括七个状态:
- 新建(New):线程对象被创建但未启动
- 就绪(Runnable):线程已启动但未获得 CPU 执行权
- 运行(Running):线程获得 CPU 执行权正在执行
- 阻塞(Blocked):线程等待获取锁
- 等待(Waiting):线程无限期等待
- 超时等待(Timed Waiting):线程有限期等待
- 终止(Terminated):线程执行完成或异常终止
2. 线程创建方式
(1) 继承 Thread 类
java
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行");
}
}
MyThread thread = new MyThread();
thread.start();
(2) 实现 Runnable 接口
java
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程执行");
}
}
Thread thread = new Thread(new MyRunnable());
thread.start();
(3) 实现 Callable 接口
java
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "线程执行结果";
}
}
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
Thread thread = new Thread(futureTask);
thread.start();
String result = futureTask.get(); // 获取线程执行结果
3. 线程同步机制
(1) synchronized 关键字
java
// 同步方法
public synchronized void method() {
// 同步代码块
}
// 同步代码块
public void method() {
synchronized (this) {
// 同步代码
}
}
(2) Lock 接口
java
Lock lock = new ReentrantLock();
try {
lock.lock();
// 同步代码
} finally {
lock.unlock();
}
4. JUC 并发工具类
- CountDownLatch:线程计数器
- CyclicBarrier:可循环使用的屏障
- Semaphore:信号量
- ConcurrentHashMap:线程安全的 HashMap
- CopyOnWriteArrayList:写时复制的 ArrayList
五、IO 流
1. IO 流的分类
- 按方向:输入流、输出流
- 按操作单位:字节流(8位)、字符流(16位)
- 按功能:节点流、处理流
2. 字节流
- InputStream/OutputStream:字节流基类
- FileInputStream/FileOutputStream:文件字节流
- BufferedInputStream/BufferedOutputStream:缓冲字节流
- ObjectInputStream/ObjectOutputStream:对象序列化流
3. 字符流
- Reader/Writer:字符流基类
- FileReader/FileWriter:文件字符流
- BufferedReader/BufferedWriter:缓冲字符流
- InputStreamReader/OutputStreamWriter:转换流
- PrintWriter:打印流
4. NIO(New IO)
- Channel:通道,双向数据传输
- Buffer:缓冲区,数据容器
- Selector:选择器,实现多路复用
java
// NIO 使用示例
try (FileChannel channel = new FileInputStream("file.txt").getChannel()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
while (bytesRead != -1) {
buffer.flip(); // 切换到读模式
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear(); // 切换到写模式
bytesRead = channel.read(buffer);
}
} catch (IOException e) {
e.printStackTrace();
}
六、Java 8 及以上新特性
1. Lambda 表达式
java
// 无参数无返回值
() -> System.out.println("Hello")
// 有参数无返回值
(String s) -> System.out.println(s)
// 有参数有返回值
(a, b) -> a + b
2. 函数式接口
只有一个抽象方法的接口,可以使用 @FunctionalInterface 注解标记。
3. Stream API
java
List<String> list = Arrays.asList("apple", "banana", "orange", "pear");
list.stream()
.filter(s -> s.length() > 5)
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
4. Optional 类
java
Optional<String> optional = Optional.ofNullable(value);
String result = optional.orElse("默认值");
5. 方法引用
java
// 静态方法引用
list.forEach(System.out::println);
// 实例方法引用
list.forEach(String::toUpperCase);
// 构造器引用
Stream.of("a", "b").map(StringBuilder::new).forEach(System.out::println);
七、总结
Java 高级特性是 Java 语言强大功能的体现,掌握这些特性对于开发复杂、高效的应用程序至关重要:
- 泛型提供了类型安全的编程方式
- 反射实现了运行时的动态性
- 注解为代码提供了丰富的元数据
- 多线程实现了并发编程
- IO流处理了数据的输入输出
- Java 8+新特性使代码更加简洁高效
通过深入学习和实践这些高级特性,可以显著提升 Java 编程能力和代码质量。