第二阶段:Java进阶技能①Java高级特性

🚀 第二阶段:Java进阶技能①Java高级特性

💡 学习目标:掌握Java高级特性,包括泛型编程、反射机制、注解与枚举,提升代码质量和开发效率

📋 目录

  1. 🔧 泛型编程
  2. 🔍 反射机制
  3. 📝 注解详解
  4. 📊 枚举类型
  5. 🎯 高级特性综合应用
  6. 🤔 常见问题与最佳实践
  7. 📝 本章小结

🔧 泛型编程

🎯 什么是泛型?

🌟 泛型:参数化类型,在编译时提供类型安全检查,避免类型转换异常

✨ 泛型的核心优势
优势说明示例
🔒 类型安全编译时检查类型错误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:泛型栈实现 ⭐⭐⭐

📝 练习描述

实现一个完整的泛型栈数据结构,支持基本栈操作和高级功能。

🎯 学习目标
  • 掌握泛型类的设计和实现
  • 理解泛型方法的使用
  • 学会实现迭代器模式
  • 掌握边界情况处理
📋 具体要求

基础要求:

  1. 实现 GenericStack<T> 类,支持 push(), pop(), peek(), isEmpty(), size() 操作
  2. 实现 Iterable<T> 接口,支持 for-each 循环遍历
  3. 处理空栈操作异常,提供清晰的错误信息

进阶要求:
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的使用
  • 掌握动态类型处理技巧
  • 学会处理复杂对象结构
  • 理解反射的性能影响
📋 具体要求

基础要求:

  1. 实现对象到 Map<String, Object> 的转换
  2. 实现Map到指定类型对象的转换
  3. 支持基本类型、字符串、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:注解驱动的数据验证器 ⭐⭐⭐⭐

📝 练习描述

设计并实现一套完整的注解驱动数据验证框架。

🎯 学习目标
  • 掌握自定义注解的设计
  • 理解注解处理器的实现
  • 学会设计可扩展的框架
  • 掌握分组验证概念
📋 具体要求

基础要求:

  1. 设计验证注解:@NotNull, @Length, @Range, @Pattern, @Email
  2. 实现统一的验证框架,提供详细的验证结果报告

进阶要求:
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:枚举状态机 ⭐⭐⭐⭐⭐

📝 练习描述

使用枚举实现一个完整的订单状态机系统,支持状态转换、事件驱动和历史记录。

🎯 学习目标
  • 掌握枚举的高级应用
  • 理解状态机设计模式
  • 学会事件驱动编程
  • 掌握观察者模式
📋 具体要求

基础要求:

  1. 设计订单状态枚举,每个状态定义允许的转换
  2. 实现基于事件的状态转换逻辑
  3. 记录状态转换历史

进阶要求:
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(对象关系映射)框架。

🎯 学习目标
  • 综合运用泛型、反射、注解、枚举
  • 理解框架设计思想
  • 掌握复杂系统的架构设计
📋 项目要求

核心功能:

  1. 实体映射:@Entity, @Table, @Column, @Id 注解
  2. 泛型DAO:通用数据访问接口,基于反射的实现
  3. 查询构建器:类型安全的查询构建,支持条件组合
  4. 事务管理:简单事务支持,事务状态枚举
💡 设计提示
@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();
}
✅ 完成标准
  • 所有基本功能正常工作
  • 代码结构清晰,注释完整
  • 异常处理恰当
  • 性能在可接受范围内
  • 通过所有测试用例

💡 学习建议

🎯 练习顺序
  1. 先完成基础练习,掌握单个特性的使用
  2. 再进行进阶练习,学会特性的综合应用
  3. 最后挑战综合项目,提升系统设计能力
🔍 重点关注
  • 泛型:类型安全、通配符使用、类型擦除
  • 反射:性能优化、安全性考虑、异常处理
  • 注解:设计原则、处理逻辑、框架集成
  • 枚举:状态机实现、策略模式、最佳实践

📝 本章小结

🎯 核心知识点回顾

🔧 泛型编程
  • ✅ 提供编译时类型安全
  • ✅ 消除强制类型转换
  • ✅ 支持通配符和边界限制
  • ✅ 提高代码复用性
🔍 反射机制
  • ✅ 运行时检查类结构
  • ✅ 动态创建对象和调用方法
  • ✅ 框架开发的重要基础
  • ⚠️ 性能开销需要考虑
📝 注解系统
  • ✅ 为代码提供元数据
  • ✅ 支持编译时和运行时处理
  • ✅ 简化配置和提高可读性
  • ✅ 框架集成的重要工具
📊 枚举类型
  • ✅ 类型安全的常量定义
  • ✅ 支持字段、方法和构造器
  • ✅ 天然的单例模式
  • ✅ 状态机实现的理想选择

📈 学习成果检验

🎯 自我检测清单
  • 能够设计和使用泛型类、泛型方法
  • 理解泛型通配符和边界的使用场景
  • 掌握反射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专家的目标前进! 🚀


📧 有问题?欢迎在评论区讨论交流!
⭐ 觉得有用?别忘了点赞收藏!
🔄 继续关注,更多精彩内容即将到来!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值