Java基础--泛型,有限条件的通配符的读写问题

目录

泛型的理解

泛型在集合,比较器中的使用

集合:

比较器:

自定义泛型类,泛型方法

自定义泛型类

格式

说明 

自定义泛型方法

格式

说明

泛型在继承上的体现

通配符"?"的使用

使用说明:

读写数据的特点(以集合ArrayList为例说明)

有限制条件的通配符    


泛型的理解

在定义类,接口的时候通过泛型标志标识类中的某个属性的类型或者是某个方法的返回值类型或参数类型,这个参数类型将在使用时确定.

如果不添加泛型,那么list集合里面可以放入任意的数据类型(引用数据类型),有着类型不安全的风险,在需要强转的时候,由于类型不确定,会出现classCastException

    @Test
    public void test() {
        ArrayList list = new ArrayList();
        list.add(new Integer(10));
        list.add("张三");
    }

泛型在集合,比较器中的使用

集合:

 @Test
    public void test2() {
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        //list.add("ABC")//编译时报错
        for (Integer integer : list) {
            System.out.println(integer);
        }

        Iterator<Integer> iterator = list.iterator();//得到迭代器
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

比较器:

    public void test3() {
        Map<String, Integer> persons = new HashMap<>();
        persons.put("Tom",18);
        persons.put("Marry",20);
        persons.put("Jerry",30);
        Set<Map.Entry<String, Integer>> entries = persons.entrySet();//得到键值对
        Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();//得到迭代器
        Set<String> strings = persons.keySet();//得到key
        Collection<Integer> values = persons.values();//得到value

       while (iterator.hasNext() ){
           Map.Entry<String, Integer> next = iterator.next();
           String key = next.getKey();//获取key时自动为String类型
           Integer value = next.getValue();//获取value自动为Integer类型

           System.out.println("KEY--->" + key + '\t' + "value--->" + value);
       }
    }

 集合框架在声明接口和实现类的时候,使用了泛型,在实例化的时候,如果没有使用泛型,那么默认为object类型,如果使用了泛型,需要指明泛型的具体类型,一旦指明了泛型的具体类型,那么所有原来有泛型的位置都以已经指明的类型为准.

自定义泛型类,泛型方法

自定义泛型类

格式

public class A <T>{
    T t;//不确定类型
    int age;
}
 class test{
     @Test
     public void test() {
         A<String> stringA = new A<>();
         stringA.age=10;
         stringA.t="张三";
     }
}

说明 

1.可以在类的属性,方法,构造器上使用泛型

2.创建对象的时候指明泛型类,则所有带泛型类的地方都是所指明的类型

3.如果没有指明泛型类,那么擦除所有泛型,默认为object类型

4.不可以使用基本数据类型定义泛型类,要使用包装类代替

5.在继承的时候:

        子类继承泛型类,实现类实现泛型接口,都可以确定泛型结构中的泛型参数

        如果我们在给泛型类提供子类的时候,如果不能确定泛型类型,那么可以继续使用泛型

        还可以在父类泛型类的基础上,子类增加新的泛型

自定义泛型方法

格式

    public<E> ArrayList<E> CopyList(E[] arg){
        ArrayList<E> list = new ArrayList<>();
        for (E e : arg) {
            list.add(e);
        }
        return list;
    }

说明

1.声明泛型方法时,一定要添加泛型参数<E>

2.泛型方法在调用的时候,指明其具体类型

3.泛型方法可以声明为static

4.泛型方法所属类可以不是泛型类

泛型在继承上的体现

1.A和a是继承关系(A--->a),G<A>,和G<a>是两个并列的类,这两个类没有任何继承关系,比如说ArrayList<String>和ArrayList<Integer>这两个类都是ArrayList肯定是没有继承关系

2A和a是继承关系(A--->a),A<M>和a<M>是继承关系,a<M>可以利用多态的性质来给A赋值,比如说List<String>和ArrayList<String>是继承关系的.(实际上在这篇文章的"泛型在集合,比较器的使用"那一章举的两个代码实例里面每个代码的第一行都使用了这个性质,用 "集合<T>"去给"集合<object>"赋值)

通配符"?"的使用

使用说明:

> 举例:ArrayList<?>

> G<?> 可以看做是G<A>类型的父类,即可以将G<A>的对象赋值给G<?>类型的引用(或变量)

读写数据的特点(以集合ArrayList<?>为例说明)

> 读取数据:允许的,读取的值的类型为Object类型

> 写入数据:不允许的。特例:写入null值。

有限制条件的通配符    

List<? extends A> : 可以将List<A>或List<B>赋值给List<? extends A>。其中B类是A类的子类。   List <? super A> :可以将List<A>或List<B>赋值给List<? extends A>。其中B类是A类的父类。

?                                    可读不可写,读为object

? extends A                    可读不可写,读为A

? super A                       可读可写,读为object

我的理解是这里实际上是多态

?代表集合里面是任何一个数据类型,但是任何数据类型都可以赋值给object类,所有都可以读出来,但是写入的时候由于不知道?代表的什么,如果?本来是B类型(object......-->A-->B-->C......下同)如果我们试图写入一个A类型,那么就出现了父类赋值给子类的情况,

? extends A实际上是?继承A或?为A,类似于数学里的小于等于这里面最大的就是A,所以是读取的时候A就一定是最父的类了,多态可以知道任何他的子类都可以给他赋值,但是如果写入的时候,就会出现第一种一样的问题

?super A ?是A或A的父类,不管?代表什么,他一定是object类或者是继承object类,那么?一定可以赋值给object,写入的时候,?是A的父类,那我们的B,C......都是A的子类,都是可以赋值给A再写入的,所以只要是A的子类的对象都是可以写入的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不爱吃于先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值