Java 泛型的应用举例说明

泛型应用

题目:

/*- 定义一个泛型类DAO<T>,在其中定义一个Map成员变量,Map的键为String类型,值为T类型
- 分别创建以下方法:
  - public void save(String id,T entity):保存T类型的对象到Map成员变量中
  - public T get(String id):从Map中获取id对应的对象
  - public void update(String id,T entity):替换map中key为id的内容,改为entity对象
  - public List<T>list():返回map中存放的所有T对象
  - public void delete(String id):删除指定id对象
- 定义一个User类:
  - 该类中包含:private成员变量(int类型)id,age;(String类型)name
- 定义一个测试类:
  - 创建DAO类的对象,分别调用其save、get、update、list、delete方法来操作User对象*/
package www.bh.c.genetest.practice;
import java.util.*;

public class DAO<T> {
    Map<String,T> map=new HashMap<>();
    //保存T类型的对象到Map成员变量中
    public void save(String id,T entity){
        map.put(id,entity);
    }
    //从Map中获取id对应的对象
    public T get(String id){
        return map.get(id);
    }
    //替换map中key为id的内容,改为entity对象
    public void update(String id,T entity){
        if (map.containsKey(id)){
            map.put(id,entity);
        }
    }
    //返回map中存放的所有T对象
    public List<T> list(){
        ArrayList<T> list = new ArrayList<>();
        Collection<T> values = map.values();
        for (T t:values){
            list.add(t);
        }
        return list;
    }
    //删除指定id对象
    public void delete(String id){
        map.remove(id);
    }
}
package www.bh.c.genetest.practice;
//定义一个User类
public class User {
    //该类中包含:private成员变量(int类型)id,age;(String类型)name
    private  int id;
    private int age;
    private String name;

    public User() {
    }

    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (id != user.id) return false;
        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }
    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + age;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}
package www.bh.c.genetest.practice;
import java.util.*;
import java.util.List;

public class DAOTest {
    //创建DAO类的对象,分别调用其save、get、update、list、delete方法来操作User对象
    public static void main(String[] args) {
        DAO<User> dao=new DAO<>();
        //save
        dao.save("001",new User(01,23,"Tom"));
        dao.save("002",new User(02,22,"Jack"));
        dao.save("003",new User(03,24,"Mary"));
        //get
        System.out.println(dao.get("002"));//User{id=2, age=22, name='Jack'}
        //update
        dao.update("003",new User(03,25,"Gary"));
        //list
        List<User> list = dao.list();
        list.forEach(System.out::println);
        System.out.println("===========");
        //User{id=1, age=23, name='Tom'}
        //User{id=2, age=22, name='Jack'}
        //User{id=3, age=25, name='Gary'}
        //delete
        dao.delete("001");
        List<User> list1 = dao.list();
        list1.forEach(a->{
            System.out.println(a);
        });
        //User{id=2, age=22, name='Jack'}
        //User{id=3, age=25, name='Gary'}
    }
}
<think>嗯,用户想了解Java的详解。首先,我需要回忆一下Java的基本概念和应用场景。Java 5引入的特性,主要用于增强类安全,减少类转换的麻烦,以及提高代码的可重用性。用户可能是在学习过程中遇到了相关的困惑,或者在实际开发中需要更深入的理解。 接下来,用户的需求可能包括了解的基本语法、类擦除、通配符、方法、类与接口,以及使用限制等。需要分步骤讲解,确保结构清晰。可能需要从为什么需要开始,然后逐步展开各个部分。 要注意的是,用户可能对类擦除这一Java的实现机制不太清楚,需要详细解释。同时,通配符部分,尤其是上下界通配符的区别和使用场景,可能是容易混淆的地方,需要举例说明。此外,在集合框架中的应用是一个常见的例子,可以用来帮助用户理解。 还需要考虑用户可能的误区,比如在运行时类信息被擦除的问题,导致无法进行instanceof判断或者创建数组。这些限制需要明确说明,避免用户在实际使用中犯错。 另外,用户可能对方法与类的区别不太清楚,需要分别举例说明。比如,方法可以在普通类中定义,而类则是整个类作用于类参数。 最后,要确保语言通俗易懂,避免过于技术性的术语,同时结合代码示例,让用户能够通过实例理解抽象的概念。检查是否有遗漏的重要知识点,比如继承、通配符捕获等,但可能根据用户的提问深度决定是否展开。</think>以下是对Java的系统化详解,分步骤解析核心概念和用法: --- ### 一、解决的问题 1. **类安全** 在集合等场景中,编译时检测类错误,避免运行时`ClassCastException` ```java // 非写法(存在隐患) List list = new ArrayList(); list.add("abc"); Integer num = (Integer) list.get(0); // 运行时异常 // 写法(编译时报错) List<String> list = new ArrayList<>(); list.add(123); // 编译错误 ``` 2. **消除强制类转换** 明确容器存储类,减少冗余代码 --- ### 二、基础语法 #### 1. 类 ```java public class Box<T> { private T content; public void setContent(T content) { this.content = content; } public T getContent() { return content; } } ``` - `T`为类参数(可任意命名,常用`T`, `E`, `K`, `V`等) - 实例化时指定具体类: ```java Box<Integer> intBox = new Box<>(); ``` #### 2. 接口 ```java public interface Comparator<T> { int compare(T o1, T o2); } ``` #### 3. 方法 ```java public <T> void printArray(T[] array) { for (T element : array) { System.out.println(element); } } ``` - 类参数声明在方法返回值前 --- ### 三、类擦除(关键机制) 1. **编译时类检查** 编译器检查合法性 2. **运行时类擦除** 生成的字节码中不包含信息,替换为原始类 ```java List<String> list = new ArrayList<>(); // 编译后等效于 List list = new ArrayList(); ``` 3. **桥方法生成** 用于保持多态性(如继承类时) --- ### 四、通配符 #### 1. 上界通配符 `<? extends T>` ```java void process(List<? extends Number> list) { // 允许读取为Number类 Number num = list.get(0); // 不允许添加元素(编译器无法确定具体子类) } ``` #### 2. 下界通配符 `<? super T>` ```java void addNumbers(List<? super Integer> list) { list.add(42); // 允许添加Integer及其父类元素 Object obj = list.get(0); // 读取只能作为Object } ``` #### 3. 无限定通配符 `<?>` ```java void printList(List<?> list) { for (Object elem : list) { System.out.println(elem); } } ``` --- ### 五、重要限制 1. **无法实例化类参数** ```java T obj = new T(); // 编译错误 ``` 2. **不能创建数组** ```java T[] array = new T[10]; // 编译错误 ``` 3. **静态上下文中不可用** ```java public class Test<T> { private static T instance; // 错误 } ``` 4. **instanceof检测无效** ```java if (list instanceof ArrayList<String>) { ... } // 编译错误 ``` --- ### 六、高级技巧 1. **类参数多重限定** ```java <T extends Comparable & Serializable> ``` 2. **与反射** ```java Type type = new TypeToken<Map<String, Integer>>(){}.getType(); ``` 3. **PECS原则** Producer-Extends, Consumer-Super (适合选择通配符边界的场景) --- ### 七、典应用场景 1. 集合框架(`ArrayList<E>`, `HashMap<K,V>`) 2. 工具类方法(`Collections.sort()`) 3. 回调接口设计(`Comparator<T>`) 4. 自定义通用数据结构 --- 通过掌握这些核心概念,可以写出类更安全、复用性更强的Java代码。建议结合具体项目实践加深理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值