🚀 第二阶段:Java进阶技能①Java高级特性
💡 学习目标:掌握Java高级特性,包括泛型编程、反射机制、注解与枚举,提升代码质量和开发效率
📋 目录
🔧 泛型编程
🎯 什么是泛型?
🌟 泛型:参数化类型,在编译时提供类型安全检查,避免类型转换异常
✨ 泛型的核心优势
| 优势 | 说明 | 示例 |
|---|---|---|
| 🔒 类型安全 | 编译时检查类型错误 | List<String> 只能存储字符串 |
| 🚫 消除强制转换 | 不需要显式类型转换 | 无需 (String) list.get(0) |
| 📈 提高性能 | 减少运行时类型检查 | 编译时确定类型 |
| 📖 增强可读性 | 代码意图更清晰 | 一眼看出集合存储的类型 |
🏗️ 泛型类的定义和使用
📝 基础泛型类
/**
* 🎯 泛型类示例:通用容器
*/
public class Container<T> {
private T item;
public Container(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
public Class<?> getItemType() {
return item != null ? item.getClass() : null;
}
}
// 使用示例
Container<String> stringContainer = new Container<>("Hello");
Container<Integer> intContainer = new Container<>(42);
Container<List<String>> listContainer = new Container<>(Arrays.asList("a", "b"));
🔄 多类型参数泛型
/**
* 🎯 多类型参数示例:键值对
*/
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
// getter和setter方法
public K getKey() { return key; }
public V getValue() { return value; }
public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
@Override
public String toString() {
return String.format("Pair{key=%s, value=%s}", key, value);
}
}
// 使用示例
Pair<String, Integer> nameAge = new Pair<>("张三", 25);
Pair<Integer, String> idName = new Pair<>(1001, "李四");
🎯 泛型方法
📝 静态泛型方法
public class GenericMethods {
/**
* 🎯 泛型方法:数组转换为列表
*/
public static <T> List<T> arrayToList(T[] array) {
List<T> list = new ArrayList<>();
for (T item : array) {
list.add(item);
}
return list;
}
/**
* 🎯 泛型方法:交换数组中两个元素
*/
public static <T> void swap(T[] array, int i, int j) {
if (i >= 0 && i < array.length && j >= 0 && j < array.length) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
/**
* 🎯 泛型方法:查找最大值
*/
public static <T extends Comparable<T>> T findMax(T[] array) {
if (array == null || array.length == 0) {
return null;
}
T max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i].compareTo(max) > 0) {
max = array[i];
}
}
return max;
}
}
🔒 泛型边界
📈 上边界通配符 (? extends)
/**
* 🎯 上边界通配符示例
*/
public class BoundedGenerics {
// 只能读取,不能添加(除了null)
public static double sumOfNumbers(List<? extends Number> numbers) {
double sum = 0.0;
for (Number num : numbers) {
sum += num.doubleValue();
}
return sum;
}
// 使用示例
public static void demonstrateUpperBound() {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
List<Double> doubles = Arrays.asList(1.1, 2.2, 3.3);
System.out.println("整数和: " + sumOfNumbers(integers));
System.out.println("小数和: " + sumOfNumbers(doubles));
}
}
📉 下边界通配符 (? super)
/**
* 🎯 下边界通配符示例
*/
public class LowerBoundedGenerics {
// 只能添加,读取时需要转换
public static void addNumbers(List<? super Integer> numbers) {
numbers.add(1);
numbers.add(2);
numbers.add(3);
// numbers.add(1.5); // 编译错误:不能添加Double
}
// 使用示例
public static void demonstrateLowerBound() {
List<Number> numbers = new ArrayList<>();
List<Object> objects = new ArrayList<>();
addNumbers(numbers);
addNumbers(objects);
System.out.println("Numbers: " + numbers);
System.out.println("Objects: " + objects);
}
}
🔍 反射机制
🎯 什么是反射?
🌟 反射:在运行时检查和操作类、方法、字段等程序结构的能力
✨ 反射的核心功能
🔍 反射能做什么?
- 📋 获取类的信息(类名、父类、接口等)
- 🔧 获取和操作字段(包括私有字段)
- 🎯 调用方法(包括私有方法)
- 🏗️ 创建对象实例
- 📝 获取注解信息
🏗️ Class对象的获取
/**
* 🎯 获取Class对象的三种方式
*/
public class ReflectionBasics {
public static void demonstrateClassObject() {
try {
// 方式1:通过类名.class
Class<?> clazz1 = String.class;
// 方式2:通过对象.getClass()
String str = "Hello";
Class<?> clazz2 = str.getClass();
// 方式3:通过Class.forName()
Class<?> clazz3 = Class.forName("java.lang.String");
// 验证三种方式获取的是同一个Class对象
System.out.println("clazz1 == clazz2: " + (clazz1 == clazz2));
System.out.println("clazz2 == clazz3: " + (clazz2 == clazz3));
// 获取类的基本信息
System.out.println("类名: " + clazz1.getName());
System.out.println("简单类名: " + clazz1.getSimpleName());
System.out.println("包名: " + clazz1.getPackage().getName());
} catch (ClassNotFoundException e) {
System.err.println("类未找到: " + e.getMessage());
}
}
}
🔧 字段操作
/**
* 🎯 反射操作字段示例
*/
public class FieldReflection {
// 示例类
static class Person {
private String name;
public int age;
protected String email;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter和setter方法省略...
}
public static void demonstrateFieldOperations() {
try {
Class<?> personClass = Person.class;
Person person = new Person("张三", 25);
// 获取所有字段(包括私有字段)
Field[] fields = personClass.getDeclaredFields();
System.out.println("=== 所有字段 ===");
for (Field field : fields) {
System.out.printf("字段: %s, 类型: %s, 修饰符: %s%n",
field.getName(),
field.getType().getSimpleName(),
Modifier.toString(field.getModifiers()));
}
// 操作私有字段
Field nameField = personClass.getDeclaredField("name");
nameField.setAccessible(true); // 设置可访问
// 读取私有字段值
String name = (String) nameField.get(person);
System.out.println("原始姓名: " + name);
// 修改私有字段值
nameField.set(person, "李四");
String newName = (String) nameField.get(person);
System.out.println("修改后姓名: " + newName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
🎯 方法调用
/**
* 🎯 反射调用方法示例
*/
public class MethodReflection {
// 示例类
static class Calculator {
public int add(int a, int b) {
return a + b;
}
private int multiply(int a, int b) {
return a * b;
}
public static int subtract(int a, int b) {
return a - b;
}
}
public static void demonstrateMethodInvocation() {
try {
Class<?> calcClass = Calculator.class;
Calculator calc = new Calculator();
// 调用公共方法
Method addMethod = calcClass.getMethod("add", int.class, int.class);
int result1 = (int) addMethod.invoke(calc, 10, 5);
System.out.println("10 + 5 = " + result1);
// 调用私有方法
Method multiplyMethod = calcClass.getDeclaredMethod("multiply", int.class, int.class);
multiplyMethod.setAccessible(true);
int result2 = (int) multiplyMethod.invoke(calc, 10, 5);
System.out.println("10 * 5 = " + result2);
// 调用静态方法
Method subtractMethod = calcClass.getMethod("subtract", int.class, int.class);
int result3 = (int) subtractMethod.invoke(null, 10, 5); // 静态方法传null
System.out.println("10 - 5 = " + result3);
} catch (Exception e) {
e.printStackTrace();
}
}
}
📝 注解详解
🎯 什么是注解?
🌟 注解:为代码提供元数据的标记,不直接影响代码执行,但可以被编译器或运行时处理
✨ 注解的分类
📋 按生命周期分类
- 🔧 SOURCE:只在源码中存在,编译时丢弃
- 📦 CLASS:编译到class文件,运行时不可见
- 🚀 RUNTIME:运行时可见,可通过反射获取
🏗️ 内置注解
/**
* 🎯 Java内置注解示例
*/
public class BuiltInAnnotations {
// @Override:标记重写方法
@Override
public String toString() {
return "BuiltInAnnotations示例";
}
// @Deprecated:标记过时方法
@Deprecated
public void oldMethod() {
System.out.println("这是一个过时的方法");
}
// @SuppressWarnings:抑制警告
@SuppressWarnings("unchecked")
public void suppressWarningsExample() {
List list = new ArrayList(); // 原始类型,会有警告
list.add("item");
}
// @SafeVarargs:标记安全的可变参数方法
@SafeVarargs
public static <T> void safeVarargsExample(T... items) {
for (T item : items) {
System.out.println(item);
}
}
// @FunctionalInterface:标记函数式接口
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}
}
🎨 自定义注解
/**
* 🎯 自定义注解示例
*/
// 方法级注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TimeMeasure {
String value() default ""; // 描述信息
boolean enabled() default true; // 是否启用
}
// 类级注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
String name() default "";
String version() default "1.0";
String[] authors() default {};
}
// 字段级注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
int min() default 0;
int max() default Integer.MAX_VALUE;
String pattern() default "";
boolean required() default false;
}
🔍 注解处理器
/**
* 🎯 注解处理器示例
*/
@Component(name = "用户服务", version = "2.0", authors = {"张三", "李四"})
public class UserService {
@Validate(min = 1, max = 100, required = true)
private int age;
@Validate(pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", required = true)
private String email;
@TimeMeasure("用户查询方法")
public void findUser(String username) {
// 模拟查询操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("查询用户: " + username);
}
@TimeMeasure(value = "用户保存方法", enabled = false)
public void saveUser(String username) {
System.out.println("保存用户: " + username);
}
}
/**
* 🎯 注解处理工具类
*/
public class AnnotationProcessor {
// 处理类级注解
public static void processClassAnnotations(Class<?> clazz) {
if (clazz.isAnnotationPresent(Component.class)) {
Component component = clazz.getAnnotation(Component.class);
System.out.println("=== 组件信息 ===");
System.out.println("名称: " + component.name());
System.out.println("版本: " + component.version());
System.out.println("作者: " + Arrays.toString(component.authors()));
}
}
// 处理字段注解
public static void processFieldAnnotations(Object obj) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Validate.class)) {
Validate validate = field.getAnnotation(Validate.class);
field.setAccessible(true);
try {
Object value = field.get(obj);
System.out.printf("验证字段 %s: ", field.getName());
if (validate.required() && value == null) {
System.out.println("❌ 必填字段不能为空");
continue;
}
if (value instanceof Integer) {
int intValue = (Integer) value;
if (intValue < validate.min() || intValue > validate.max()) {
System.out.printf("❌ 值 %d 不在范围 [%d, %d] 内%n",
intValue, validate.min(), validate.max());
} else {
System.out.println("✅ 验证通过");
}
}
if (value instanceof String && !validate.pattern().isEmpty()) {
String strValue = (String) value;
if (!strValue.matches(validate.pattern())) {
System.out.println("❌ 格式不正确");
} else {
System.out.println("✅ 验证通过");
}
}
} catch (IllegalAccessException e) {
System.out.println("❌ 无法访问字段");
}
}
}
}
// 处理方法注解(时间测量)
public static Object processMethodAnnotations(Object obj, String methodName, Object... args) {
try {
Class<?> clazz = obj.getClass();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals(methodName) && method.isAnnotationPresent(TimeMeasure.class)) {
TimeMeasure timeMeasure = method.getAnnotation(TimeMeasure.class);
if (!timeMeasure.enabled()) {
System.out.println("⏸️ 时间测量已禁用: " + timeMeasure.value());
return method.invoke(obj, args);
}
long startTime = System.currentTimeMillis();
Object result = method.invoke(obj, args);
long endTime = System.currentTimeMillis();
System.out.printf("⏱️ %s 执行时间: %d ms%n",
timeMeasure.value().isEmpty() ? methodName : timeMeasure.value(),
endTime - startTime);
return result;
}
}
// 如果没有找到注解,正常调用方法
Method method = clazz.getMethod(methodName);
return method.invoke(obj, args);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
📊 枚举类型
🎯 什么是枚举?
🌟 枚举:一种特殊的类,用于定义一组固定的常量,提供类型安全和更好的可读性
✨ 枚举的优势
🎯 为什么使用枚举?
- 🔒 类型安全:编译时检查,避免无效值
- 📖 可读性强:语义明确,代码自文档化
- 🛡️ 单例保证:每个枚举常量都是单例
- 🔧 功能丰富:可以有字段、方法、构造器
🏗️ 基础枚举
/**
* 🎯 基础枚举示例
*/
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
// 判断是否为工作日
public boolean isWeekday() {
return this != SATURDAY && this != SUNDAY;
}
// 判断是否为周末
public boolean isWeekend() {
return this == SATURDAY || this == SUNDAY;
}
}
/**
* 🎯 使用基础枚举
*/
public class BasicEnumExample {
public static void demonstrateBasicEnum() {
// 遍历所有枚举值
System.out.println("=== 所有星期 ===");
for (Day day : Day.values()) {
System.out.printf("%s: 工作日=%s, 周末=%s%n",
day, day.isWeekday(), day.isWeekend());
}
// 字符串转枚举
Day today = Day.valueOf("MONDAY");
System.out.println("今天是: " + today);
// 枚举比较
if (today == Day.MONDAY) {
System.out.println("周一,新的开始!");
}
// 获取枚举序号
System.out.println("MONDAY的序号: " + Day.MONDAY.ordinal());
}
}
🎨 复杂枚举
/**
* 🎯 带字段和方法的复杂枚举
*/
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6),
JUPITER(1.9e+27, 7.1492e7),
SATURN(5.688e+26, 6.0268e7),
URANUS(8.686e+25, 2.5559e7),
NEPTUNE(1.024e+26, 2.4746e7);
private final double mass; // 质量(千克)
private final double radius; // 半径(米)
// 构造器
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
// 访问器方法
public double getMass() { return mass; }
public double getRadius() { return radius; }
// 万有引力常数
public static final double G = 6.67300E-11;
// 计算表面重力
public double surfaceGravity() {
return G * mass / (radius * radius);
}
// 计算在该星球上的重量
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
/**
* 🎯 状态机枚举示例
*/
public enum OrderStatus {
PENDING("待处理", "订单已创建,等待处理") {
@Override
public OrderStatus nextStatus() {
return CONFIRMED;
}
@Override
public boolean canCancel() {
return true;
}
},
CONFIRMED("已确认", "订单已确认,准备发货") {
@Override
public OrderStatus nextStatus() {
return SHIPPED;
}
@Override
public boolean canCancel() {
return true;
}
},
SHIPPED("已发货", "订单已发货,正在运输中") {
@Override
public OrderStatus nextStatus() {
return DELIVERED;
}
@Override
public boolean canCancel() {
return false;
}
},
DELIVERED("已送达", "订单已送达客户") {
@Override
public OrderStatus nextStatus() {
return COMPLETED;
}
@Override
public boolean canCancel() {
return false;
}
},
COMPLETED("已完成", "订单已完成") {
@Override
public OrderStatus nextStatus() {
return this; // 已完成状态不能转换
}
@Override
public boolean canCancel() {
return false;
}
},
CANCELLED("已取消", "订单已取消") {
@Override
public OrderStatus nextStatus() {
return this; // 已取消状态不能转换
}
@Override
public boolean canCancel() {
return false;
}
};
private final String displayName;
private final String description;
OrderStatus(String displayName, String description) {
this.displayName = displayName;
this.description = description;
}
public String getDisplayName() { return displayName; }
public String getDescription() { return description; }
// 抽象方法,每个枚举值必须实现
public abstract OrderStatus nextStatus();
public abstract boolean canCancel();
// 取消订单
public OrderStatus cancel() {
if (canCancel()) {
return CANCELLED;
}
throw new IllegalStateException("订单状态 " + this.displayName + " 不能取消");
}
}
🔧 枚举工具类
/**
* 🎯 枚举工具类示例
*/
public class EnumUtils {
/**
* 安全地将字符串转换为枚举
*/
public static <T extends Enum<T>> T safeValueOf(Class<T> enumClass, String name, T defaultValue) {
try {
return Enum.valueOf(enumClass, name.toUpperCase());
} catch (IllegalArgumentException | NullPointerException e) {
return defaultValue;
}
}
/**
* 获取枚举的所有显示名称
*/
public static List<String> getDisplayNames(OrderStatus[] statuses) {
return Arrays.stream(statuses)
.map(OrderStatus::getDisplayName)
.collect(Collectors.toList());
}
/**
* 根据显示名称查找枚举
*/
public static OrderStatus findByDisplayName(String displayName) {
return Arrays.stream(OrderStatus.values())
.filter(status -> status.getDisplayName().equals(displayName))
.findFirst()
.orElse(null);
}
}
🎯 高级特性综合应用
🏗️ 综合示例:通用数据访问层
/**
* 🎯 综合应用:通用数据访问层
* 结合泛型、反射、注解的实际应用
*/
// 实体注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
String tableName() default "";
}
// 字段注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String name() default "";
boolean primaryKey() default false;
boolean nullable() default true;
}
// 示例实体类
@Entity(tableName = "users")
public class User {
@Column(name = "id", primaryKey = true, nullable = false)
private Long id;
@Column(name = "username", nullable = false)
private String username;
@Column(name = "email")
private String email;
@Column(name = "age")
private Integer age;
// 构造器、getter、setter方法
public User() {}
public User(Long id, String username, String email, Integer age) {
this.id = id;
this.username = username;
this.email = email;
this.age = age;
}
// getter和setter方法省略...
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
@Override
public String toString() {
return String.format("User{id=%d, username='%s', email='%s', age=%d}",
id, username, email, age);
}
}
/**
* 🎯 通用数据访问接口
*/
public interface GenericDao<T, ID> {
void save(T entity);
T findById(ID id);
List<T> findAll();
void update(T entity);
void delete(ID id);
}
/**
* 🎯 基于反射的通用数据访问实现
*/
public class ReflectionBasedDao<T, ID> implements GenericDao<T, ID> {
private final Class<T> entityClass;
private final Map<ID, T> dataStore = new HashMap<>();
@SuppressWarnings("unchecked")
public ReflectionBasedDao() {
// 通过反射获取泛型类型
Type superClass = getClass().getGenericSuperclass();
if (superClass instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) superClass;
this.entityClass = (Class<T>) parameterizedType.getActualTypeArguments()[0];
} else {
throw new IllegalStateException("无法确定实体类型");
}
}
public ReflectionBasedDao(Class<T> entityClass) {
this.entityClass = entityClass;
}
@Override
public void save(T entity) {
try {
ID id = getPrimaryKeyValue(entity);
if (id == null) {
// 生成新ID(简化实现)
id = generateId();
setPrimaryKeyValue(entity, id);
}
dataStore.put(id, entity);
System.out.println("保存实体: " + entity);
} catch (Exception e) {
throw new RuntimeException("保存实体失败", e);
}
}
@Override
public T findById(ID id) {
T entity = dataStore.get(id);
System.out.println("查找实体 ID=" + id + ": " + entity);
return entity;
}
@Override
public List<T> findAll() {
List<T> result = new ArrayList<>(dataStore.values());
System.out.println("查找所有实体,共 " + result.size() + " 条");
return result;
}
@Override
public void update(T entity) {
try {
ID id = getPrimaryKeyValue(entity);
if (id != null && dataStore.containsKey(id)) {
dataStore.put(id, entity);
System.out.println("更新实体: " + entity);
} else {
throw new IllegalArgumentException("实体不存在,无法更新");
}
} catch (Exception e) {
throw new RuntimeException("更新实体失败", e);
}
}
@Override
public void delete(ID id) {
T removed = dataStore.remove(id);
if (removed != null) {
System.out.println("删除实体 ID=" + id + ": " + removed);
} else {
System.out.println("实体 ID=" + id + " 不存在");
}
}
// 获取主键值
@SuppressWarnings("unchecked")
private ID getPrimaryKeyValue(T entity) throws Exception {
Field primaryKeyField = getPrimaryKeyField();
primaryKeyField.setAccessible(true);
return (ID) primaryKeyField.get(entity);
}
// 设置主键值
private void setPrimaryKeyValue(T entity, ID id) throws Exception {
Field primaryKeyField = getPrimaryKeyField();
primaryKeyField.setAccessible(true);
primaryKeyField.set(entity, id);
}
// 获取主键字段
private Field getPrimaryKeyField() {
for (Field field : entityClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Column.class)) {
Column column = field.getAnnotation(Column.class);
if (column.primaryKey()) {
return field;
}
}
}
throw new IllegalStateException("未找到主键字段");
}
// 生成ID(简化实现)
@SuppressWarnings("unchecked")
private ID generateId() {
return (ID) Long.valueOf(System.currentTimeMillis() % 100000);
}
// 获取表名
public String getTableName() {
if (entityClass.isAnnotationPresent(Entity.class)) {
Entity entity = entityClass.getAnnotation(Entity.class);
String tableName = entity.tableName();
return tableName.isEmpty() ? entityClass.getSimpleName().toLowerCase() : tableName;
}
return entityClass.getSimpleName().toLowerCase();
}
// 获取所有列信息
public Map<String, Field> getColumnFields() {
Map<String, Field> columnFields = new HashMap<>();
for (Field field : entityClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Column.class)) {
Column column = field.getAnnotation(Column.class);
String columnName = column.name().isEmpty() ? field.getName() : column.name();
columnFields.put(columnName, field);
}
}
return columnFields;
}
}
/**
* 🎯 用户数据访问层
*/
public class UserDao extends ReflectionBasedDao<User, Long> {
public UserDao() {
super(User.class);
}
// 可以添加特定的查询方法
public List<User> findByUsername(String username) {
return findAll().stream()
.filter(user -> username.equals(user.getUsername()))
.collect(Collectors.toList());
}
public List<User> findByAgeRange(int minAge, int maxAge) {
return findAll().stream()
.filter(user -> user.getAge() != null)
.filter(user -> user.getAge() >= minAge && user.getAge() <= maxAge)
.collect(Collectors.toList());
}
}
🎮 综合应用演示
/**
* 🎯 高级特性综合演示
*/
public class AdvancedFeaturesDemo {
public static void main(String[] args) {
System.out.println("🚀 Java高级特性综合演示");
System.out.println("=" .repeat(50));
// 1. 泛型演示
demonstrateGenerics();
// 2. 反射演示
demonstrateReflection();
// 3. 注解演示
demonstrateAnnotations();
// 4. 枚举演示
demonstrateEnums();
// 5. 综合应用演示
demonstrateIntegratedExample();
}
private static void demonstrateGenerics() {
System.out.println("\n🔧 泛型演示");
System.out.println("-".repeat(30));
// 泛型容器
Container<String> stringContainer = new Container<>("Hello Generics");
System.out.println("字符串容器: " + stringContainer.getItem());
// 泛型方法
String[] names = {"张三", "李四", "王五"};
List<String> nameList = GenericMethods.arrayToList(names);
System.out.println("数组转列表: " + nameList);
// 边界通配符
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
double sum = BoundedGenerics.sumOfNumbers(numbers);
System.out.println("数字求和: " + sum);
}
private static void demonstrateReflection() {
System.out.println("\n🔍 反射演示");
System.out.println("-".repeat(30));
// 基础反射
ReflectionBasics.demonstrateClassObject();
// 字段操作
FieldReflection.demonstrateFieldOperations();
// 方法调用
MethodReflection.demonstrateMethodInvocation();
}
private static void demonstrateAnnotations() {
System.out.println("\n📝 注解演示");
System.out.println("-".repeat(30));
UserService userService = new UserService();
// 处理类注解
AnnotationProcessor.processClassAnnotations(UserService.class);
// 处理字段注解
AnnotationProcessor.processFieldAnnotations(userService);
// 处理方法注解
AnnotationProcessor.processMethodAnnotations(userService, "findUser", "张三");
AnnotationProcessor.processMethodAnnotations(userService, "saveUser", "李四");
}
private static void demonstrateEnums() {
System.out.println("\n📊 枚举演示");
System.out.println("-".repeat(30));
// 基础枚举
BasicEnumExample.demonstrateBasicEnum();
// 复杂枚举 - 行星
System.out.println("\n=== 行星信息 ===");
double earthWeight = 70.0; // 地球上70公斤
for (Planet planet : Planet.values()) {
double weight = planet.surfaceWeight(earthWeight);
System.out.printf("在%s上的重量: %.2f kg%n", planet, weight);
}
// 状态机枚举
System.out.println("\n=== 订单状态流转 ===");
OrderStatus status = OrderStatus.PENDING;
System.out.println("初始状态: " + status.getDisplayName());
while (status != OrderStatus.COMPLETED && status != OrderStatus.CANCELLED) {
OrderStatus nextStatus = status.nextStatus();
System.out.printf("%s -> %s%n", status.getDisplayName(), nextStatus.getDisplayName());
status = nextStatus;
}
}
private static void demonstrateIntegratedExample() {
System.out.println("\n🎯 综合应用演示");
System.out.println("-".repeat(30));
// 创建用户DAO
UserDao userDao = new UserDao();
// 创建用户
User user1 = new User(null, "张三", "zhangsan@example.com", 25);
User user2 = new User(null, "李四", "lisi@example.com", 30);
User user3 = new User(null, "王五", "wangwu@example.com", 28);
// 保存用户
userDao.save(user1);
userDao.save(user2);
userDao.save(user3);
// 查询用户
System.out.println("\n查询所有用户:");
userDao.findAll().forEach(System.out::println);
// 按用户名查询
System.out.println("\n按用户名查询:");
userDao.findByUsername("张三").forEach(System.out::println);
// 按年龄范围查询
System.out.println("\n按年龄范围查询(25-30岁):");
userDao.findByAgeRange(25, 30).forEach(System.out::println);
// 显示表信息
System.out.println("\n表名: " + userDao.getTableName());
System.out.println("列信息: " + userDao.getColumnFields().keySet());
}
}
🤔 常见问题与最佳实践
⚠️ 泛型常见陷阱
🚨 类型擦除问题
public class GenericTraps {
// ❌ 错误:不能创建泛型数组
// T[] array = new T[10]; // 编译错误
// ✅ 正确:使用Object数组并转换
@SuppressWarnings("unchecked")
public static <T> T[] createArray(Class<T> clazz, int size) {
return (T[]) Array.newInstance(clazz, size);
}
// ❌ 错误:不能使用instanceof检查泛型类型
public static <T> boolean checkType(Object obj) {
// return obj instanceof T; // 编译错误
return false;
}
// ✅ 正确:传递Class对象进行类型检查
public static <T> boolean checkType(Object obj, Class<T> clazz) {
return clazz.isInstance(obj);
}
}
🔍 反射性能优化
💡 反射缓存策略
public class ReflectionCache {
// 缓存Class对象
private static final Map<String, Class<?>> classCache = new ConcurrentHashMap<>();
// 缓存Method对象
private static final Map<String, Method> methodCache = new ConcurrentHashMap<>();
// 缓存Field对象
private static final Map<String, Field> fieldCache = new ConcurrentHashMap<>();
public static Class<?> getClass(String className) {
return classCache.computeIfAbsent(className, name -> {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
throw new RuntimeException("类未找到: " + name, e);
}
});
}
public static Method getMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
String key = clazz.getName() + "#" + methodName + "#" + Arrays.toString(paramTypes);
return methodCache.computeIfAbsent(key, k -> {
try {
return clazz.getMethod(methodName, paramTypes);
} catch (NoSuchMethodException e) {
throw new RuntimeException("方法未找到: " + methodName, e);
}
});
}
public static Field getField(Class<?> clazz, String fieldName) {
String key = clazz.getName() + "#" + fieldName;
return fieldCache.computeIfAbsent(key, k -> {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("字段未找到: " + fieldName, e);
}
});
}
}
📝 注解最佳实践
🎯 注解设计原则
/**
* ✅ 好的注解设计
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cache {
// 提供默认值
String key() default "";
// 使用枚举而不是字符串
CacheType type() default CacheType.MEMORY;
// 合理的数值范围
int expireSeconds() default 300;
// 布尔值有明确含义
boolean nullable() default false;
enum CacheType {
MEMORY, REDIS, DATABASE
}
}
/**
* ❌ 不好的注解设计
*/
@Retention(RetentionPolicy.RUNTIME) // 缺少@Target
public @interface BadCache {
String value(); // 没有默认值,使用不便
String type(); // 应该使用枚举
int expire(); // 没有默认值和单位说明
}
📊 枚举最佳实践
🎨 枚举设计建议
/**
* ✅ 好的枚举设计
*/
public enum HttpStatus {
// 信息响应
CONTINUE(100, "Continue"),
SWITCHING_PROTOCOLS(101, "Switching Protocols"),
// 成功响应
OK(200, "OK"),
CREATED(201, "Created"),
ACCEPTED(202, "Accepted"),
// 客户端错误
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
FORBIDDEN(403, "Forbidden"),
NOT_FOUND(404, "Not Found"),
// 服务器错误
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
BAD_GATEWAY(502, "Bad Gateway"),
SERVICE_UNAVAILABLE(503, "Service Unavailable");
private final int code;
private final String reasonPhrase;
HttpStatus(int code, String reasonPhrase) {
this.code = code;
this.reasonPhrase = reasonPhrase;
}
public int getCode() { return code; }
public String getReasonPhrase() { return reasonPhrase; }
// 提供便捷的查找方法
public static HttpStatus valueOf(int code) {
for (HttpStatus status : values()) {
if (status.code == code) {
return status;
}
}
throw new IllegalArgumentException("未知的HTTP状态码: " + code);
}
// 提供分类方法
public boolean isInformational() { return code >= 100 && code < 200; }
public boolean isSuccessful() { return code >= 200 && code < 300; }
public boolean isRedirection() { return code >= 300 && code < 400; }
public boolean isClientError() { return code >= 400 && code < 500; }
public boolean isServerError() { return code >= 500 && code < 600; }
@Override
public String toString() {
return code + " " + reasonPhrase;
}
}
🎯 性能考虑
📊 性能对比表
| 特性 | 性能影响 | 使用建议 | 注意事项 |
|---|---|---|---|
| 🔧 泛型 | ✅ 无运行时开销 | 大量使用 | 注意类型擦除 |
| 🔍 反射 | ❌ 性能开销较大 | 谨慎使用,考虑缓存 | 破坏封装性 |
| 📝 注解 | ✅ 编译时处理无开销 | 适度使用 | 运行时注解有开销 |
| 📊 枚举 | ✅ 性能优秀 | 推荐使用 | 内存占用略高 |
🎯 实战练习作业
📋 练习概览
通过以下实战练习,巩固和深化对Java高级特性的理解和应用能力。
🎯 练习难度说明
- ⭐⭐⭐ 基础练习:适合初学者,重点掌握基本概念
- ⭐⭐⭐⭐ 进阶练习:需要一定基础,综合运用多个特性
- ⭐⭐⭐⭐⭐ 高级练习:具有挑战性,需要深入理解和创新思维
🔧 练习1:泛型栈实现 ⭐⭐⭐
📝 练习描述
实现一个完整的泛型栈数据结构,支持基本栈操作和高级功能。
🎯 学习目标
- 掌握泛型类的设计和实现
- 理解泛型方法的使用
- 学会实现迭代器模式
- 掌握边界情况处理
📋 具体要求
基础要求:
- 实现
GenericStack<T>类,支持push(),pop(),peek(),isEmpty(),size()操作 - 实现
Iterable<T>接口,支持 for-each 循环遍历 - 处理空栈操作异常,提供清晰的错误信息
进阶要求:
4. 实现批量操作:pushAll(), popAll(), toArray()
5. 应用实例:括号匹配检查、逆波兰表达式计算
💡 实现提示
public class GenericStack<T> implements Iterable<T> {
private Node<T> top;
private int size;
private static class Node<T> {
T data;
Node<T> next;
}
// 实现栈操作和迭代器
}
🔍 练习2:反射对象映射器 ⭐⭐⭐⭐
📝 练习描述
使用反射技术实现对象与Map之间的相互转换,以及对象深拷贝功能。
🎯 学习目标
- 深入理解反射API的使用
- 掌握动态类型处理技巧
- 学会处理复杂对象结构
- 理解反射的性能影响
📋 具体要求
基础要求:
- 实现对象到
Map<String, Object>的转换 - 实现Map到指定类型对象的转换
- 支持基本类型、字符串、null值处理
进阶要求:
4. 递归处理嵌套对象、集合类型、数组类型
5. 实现对象深拷贝功能
6. 提供对象比较 deepEquals() 方法
💡 实现提示
public class ObjectMapper {
public static Map<String, Object> objectToMap(Object obj) {
// 使用反射获取字段并转换
}
public static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) {
// 使用反射创建对象并设置字段值
}
}
📝 练习3:注解驱动的数据验证器 ⭐⭐⭐⭐
📝 练习描述
设计并实现一套完整的注解驱动数据验证框架。
🎯 学习目标
- 掌握自定义注解的设计
- 理解注解处理器的实现
- 学会设计可扩展的框架
- 掌握分组验证概念
📋 具体要求
基础要求:
- 设计验证注解:
@NotNull,@Length,@Range,@Pattern,@Email - 实现统一的验证框架,提供详细的验证结果报告
进阶要求:
3. 支持自定义验证器:@CustomValidator 注解
4. 实现分组验证功能,支持不同场景的验证规则
5. 性能优化:验证结果缓存、反射操作优化
💡 实现提示
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
String message() default "字段不能为空";
String[] groups() default {};
}
public class DataValidator {
public static ValidationResult validate(Object obj, String... groups) {
// 使用反射获取注解并执行验证
}
}
📊 练习4:枚举状态机 ⭐⭐⭐⭐⭐
📝 练习描述
使用枚举实现一个完整的订单状态机系统,支持状态转换、事件驱动和历史记录。
🎯 学习目标
- 掌握枚举的高级应用
- 理解状态机设计模式
- 学会事件驱动编程
- 掌握观察者模式
📋 具体要求
基础要求:
- 设计订单状态枚举,每个状态定义允许的转换
- 实现基于事件的状态转换逻辑
- 记录状态转换历史
进阶要求:
4. 实现事件驱动机制和状态转换监听器
5. 提供状态统计信息和转换路径分析
6. 支持并发安全的状态管理
💡 实现提示
public enum OrderState {
PENDING("待支付") {
@Override
public Set<OrderState> getAllowedTransitions() {
return EnumSet.of(PAID, CANCELLED);
}
};
public abstract Set<OrderState> getAllowedTransitions();
}
public class OrderStateMachine {
public boolean transition(String orderId, OrderEvent event, String reason) {
// 实现状态转换逻辑
}
}
🎯 综合项目:简易ORM框架 ⭐⭐⭐⭐⭐
📝 项目描述
结合所有Java高级特性,实现一个简易的ORM(对象关系映射)框架。
🎯 学习目标
- 综合运用泛型、反射、注解、枚举
- 理解框架设计思想
- 掌握复杂系统的架构设计
📋 项目要求
核心功能:
- 实体映射:
@Entity,@Table,@Column,@Id注解 - 泛型DAO:通用数据访问接口,基于反射的实现
- 查询构建器:类型安全的查询构建,支持条件组合
- 事务管理:简单事务支持,事务状态枚举
💡 设计提示
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "id")
private Long id;
@Column(name = "username")
private String username;
}
public interface GenericDao<T, ID> {
void save(T entity);
T findById(ID id);
List<T> findAll();
}
✅ 完成标准
- 所有基本功能正常工作
- 代码结构清晰,注释完整
- 异常处理恰当
- 性能在可接受范围内
- 通过所有测试用例
💡 学习建议
🎯 练习顺序
- 先完成基础练习,掌握单个特性的使用
- 再进行进阶练习,学会特性的综合应用
- 最后挑战综合项目,提升系统设计能力
🔍 重点关注
- 泛型:类型安全、通配符使用、类型擦除
- 反射:性能优化、安全性考虑、异常处理
- 注解:设计原则、处理逻辑、框架集成
- 枚举:状态机实现、策略模式、最佳实践
📝 本章小结
🎯 核心知识点回顾
🔧 泛型编程
- ✅ 提供编译时类型安全
- ✅ 消除强制类型转换
- ✅ 支持通配符和边界限制
- ✅ 提高代码复用性
🔍 反射机制
- ✅ 运行时检查类结构
- ✅ 动态创建对象和调用方法
- ✅ 框架开发的重要基础
- ⚠️ 性能开销需要考虑
📝 注解系统
- ✅ 为代码提供元数据
- ✅ 支持编译时和运行时处理
- ✅ 简化配置和提高可读性
- ✅ 框架集成的重要工具
📊 枚举类型
- ✅ 类型安全的常量定义
- ✅ 支持字段、方法和构造器
- ✅ 天然的单例模式
- ✅ 状态机实现的理想选择
📈 学习成果检验
🎯 自我检测清单
- 能够设计和使用泛型类、泛型方法
- 理解泛型通配符和边界的使用场景
- 掌握反射API的基本使用
- 能够设计和处理自定义注解
- 熟练使用枚举类型解决实际问题
- 了解各种特性的性能影响和最佳实践
🚀 进阶学习方向
| 方向 | 内容 | 推荐资源 |
|---|---|---|
| 🔧 泛型深入 | 类型推断、PECS原则 | 《Effective Java》 |
| 🔍 反射应用 | 动态代理、框架原理 | Spring源码分析 |
| 📝 注解处理器 | 编译时代码生成 | APT技术文档 |
| 📊 枚举模式 | 状态机、策略模式 | 设计模式相关书籍 |
🗺️ 专栏学习路径图
📈 Java程序员从0到1成长路径
🎯 第一阶段:Java基础入门 (4-6周) - ✅ 已完成
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1.开发环境 │───▶│ 2.基础语法 │───▶│ 3.面向对象 │───▶│ 4.核心API │
│ 搭建 │ │ │ │ 编程基础 │ │ │
│ ✅ 已完成 │ │ ✅ 已完成 │ │ ✅ 已完成 │ │ ✅ 已完成 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
🚀 第二阶段:Java进阶技能 (4-6周)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1.高级特性 │ │ 2.I/O与网络 │ │ 3.新特性 │ │ 4.工具框架 │
│ │ │ 编程 │ │ │ │ 入门 │
│ ✅ 已完成 │ │ 🎯 下一步 │ │ 📅 计划中 │ │ 📅 计划中 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
🎯 第三阶段:项目实战 (4-8周)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1.小型项目 │ │ 2.Web开发 │ │ 3.Spring │ │ 4.数据库与 │
│ 开发 │ │ 基础 │ │ 框架入门 │ │ 持久层 │
│ 📅 计划中 │ │ 📅 计划中 │ │ 📅 计划中 │ │ 📅 计划中 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
🏆 第四阶段:职业发展 (持续更新)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1.代码质量 │ │ 2.开发工具 │ │ 3.面试准备 │ │ 4.职业规划 │
│ 与规范 │ │ 链 │ │ │ │ │
│ 📅 计划中 │ │ 📅 计划中 │ │ 📅 计划中 │ │ 📅 计划中 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
📋 第二阶段学习进度
| 章节 | 主要内容 | 预计时间 | 难度 | 状态 |
|---|---|---|---|---|
| 🔧 1.Java高级特性 | 泛型、反射、注解、枚举 | 1-2周 | ⭐⭐⭐⭐ | ✅ 已完成 |
| 📁 2.I/O与网络编程 | 文件操作、网络通信、多线程 | 1-2周 | ⭐⭐⭐⭐ | 🎯 下一步 |
| 🆕 3.Java新特性 | Lambda、Stream API、模块化 | 1周 | ⭐⭐⭐⭐ | 📅 计划中 |
| 🛠️ 4.工具与框架入门 | Maven/Gradle、JUnit、日志框架 | 1周 | ⭐⭐⭐ | 📅 计划中 |
• 第二阶段进度:25% (1/4章节完成)
• 下一步:学习Java I/O与网络编程
• 建议:巩固高级特性知识,准备学习I/O操作
• 重点:掌握文件操作、网络通信和多线程编程
🎬 下一章预告
📁 第二阶段第2章:Java I/O与网络编程
🎯 下章学习内容
- 📂 文件操作与I/O流体系
- 🌐 网络通信基础与Socket编程
- 🧵 多线程编程与并发控制
- 🔄 NIO与异步编程模型
💡 学习建议
- 结合实际项目练习I/O操作
- 理解阻塞与非阻塞I/O的区别
- 掌握多线程的基本概念和应用
- 学习线程安全和并发编程最佳实践
🎉 恭喜完成Java高级特性的学习!
你已经掌握了Java编程的高级技能,
这些特性是构建复杂应用程序的重要基础!
继续保持学习的热情,向着Java专家的目标前进! 🚀
📧 有问题?欢迎在评论区讨论交流!
⭐ 觉得有用?别忘了点赞收藏!
🔄 继续关注,更多精彩内容即将到来!






