泛型

1 泛型在类上的引用

【案例1】创建类MyData,使用<>就有了泛型

public class MyData<T> {
    private T data;

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

【案例2】使用泛型

public class TestOne {
    public static void main(String[] args) {
        // 在创建支持泛型的类的对象时给出泛型的具体类型
        // 支持泛型的类在不给出泛型具体类型时,泛型被当做Object
        // 引用类型的泛型必须和对象类型的泛型一致,泛型不支持多态

        // 方式一 — 不推荐
        // MyData<String> myData = new MyData<String>();

        // 方式二 — 不推荐
        // MyData<String> myData = new MyData();

        // 方式三 — 推荐使用
        MyData<String> myData = new MyData<>();
        myData.setData("Tom");
        System.out.println(myData.getData());

    }
}

【案例3】

// 1. 方式一
// 在子类继承父类时给出父类的泛型具体类型(这里是String)
public class SubMyData extends MyData<String> {
    @Override
    public String getData() {
        return super.getData();
    }

    @Override
    public void setData(String data) {
        super.setData(data);
    }

// 方式二
// 子类继承父类的泛型,子类也做成泛型的类
public class SubMyData<T> extends MyData<T> {
    
    @Override
    public T getData() {
        return super.getData();
    }

    @Override
    public void setData(T data) {
        super.setData(data);
    }
}

 

2 泛型在接口上的使用

【案例1】

public interface MyInterOne<T> {
    //1.静态成员不支持泛型
    // public static final T data;    ×

    //2.泛型在方法上的使用
    //2.1 返回值是泛型
    public T methodOne();
    //2.2 参数是泛型
    public void methodTwo(T t);
    //2.3 返回值、参数都是泛型
    public T methodThree(T t);
}

【案例2】推荐方式三

// 1.接口的泛型需要在实现类实现接口时确定泛型的具体类型
// 如果实现类没有确定泛型的具体的类型则视作Object
public class MyInterOneImpl implements MyInterOne {
    @Override
    public Object methodOne() {
        return null;
    }

    @Override
    public void methodTwo(Object o) {

    }

    @Override
    public Object methodThree(Object o) {
        return null;
    }




// 2. 实现类实现泛型时给出泛型的具体类型
 public class MyInterOneImpl implements MyInterOne<String> {
    @Override
    public String methodOne() {
        return null;
    }

    @Override
    public void methodTwo(String s) {

    }

    @Override
    public String methodThree(String s) {
        return null;
    }



// 3.实现类实现接口时继承接口的泛型
public class MyInterOneImpl<T> implements MyInterOne<T> {

    @Override
    public T methodOne() {
        return null;
    }

    @Override
    public void methodTwo(T t) {

    }

    @Override
    public T methodThree(T t) {
        return null;
    }
}

【案例3】

public class TestTwo {
    public static void main(String[] args) {
        // 创建接口实现类对象时给出泛型的具体类型
        MyInterOne<String> myInterOne = new MyInterOneImpl<>();
    }
}

 

3 类型通配符

public class TestThree {
    public static void main(String[] args) {
        Collection<String> col1 = new ArrayList<>();
        col1.add("Tom");
        col1.add("Jerry");
        col1.add("Mary");
        
        Collection<Integer> col2 = new ArrayList<>();
        col2.add(10);
        col2.add(20);
        col2.add(30);
        
        methodOne(col1);
        methodTwo(col1);
        methodOne(col2);
        // methodTwo(col2);
        methodThree(col1);
        methodThree(col2);

        Collection<Animal> col3 = new ArrayList<>();
        Collection<Dog> col4 = new ArrayList<>();
        Collection<Cat> col5 = new ArrayList<>();

        methodThree(col3);
        methodFour(col3);
        methodFour(col4);
        methodFour(col5);
        methodFive(col3);
        // methodFive(col4);
        methodFive(col5);
    }

    public static void methodOne(Collection col){
        for (Object o : col) {
            System.out.println(o);
        }
    }

    public static void methodTwo(Collection<String> col){
        for (String s : col) {
            System.out.println(s);
        }
    }

    // ?是泛型形参的通配类型,这种类型可以匹配任何支持泛型的实参
    public static void methodThree(Collection<?> col){
        for (Object o : col) {
            System.out.println(o);
        }
    }

    // 这种方式指定了泛型通配的父类,可以包含父类及父类的子类类型,相当于指定了泛型的上限
    public static void methodFour(Collection<? extends Animal> col){
        for (Animal animal : col) {
            System.out.println(animal);
        }
    }

    // 这种方式指定了通配类型必须是Cat或者Cat的父类对象,相当于指定了泛型的下限
    public static void methodFive(Collection<? super Cat> col){
        for (Object o : col) {
            System.out.println(o);
        }
    }
}

class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}

 

4 泛型的集合

【案例】

public class TestFour {
    public static void main(String[] args) {
        // 泛型的集合
        List<String> list = new ArrayList<>();
        list.add("Tom");
        String s = list.get(0);

        // 迭代器可以指定泛型,但是迭代器的泛型必须和集合的泛型一致
        Iterator<String> iter = list.iterator();

        Map<String, Student> map = new HashMap<>();
        // Map可以单独指定键和值的泛型,键集泛型必须和键泛型一致,值集泛型必须和值泛型一致
        Set<String> keys = map.keySet();
        Collection<Student> values = map.values();
    }
}

 

posted @   白森  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
历史上的今天:
2022-05-13 电商数据仓库系统
点击右上角即可分享
微信分享提示