Java基础之——泛型(二) 通配符


说在前头的话:如果迷茫,请做好当下的事!

上一篇讲了泛型的基本知识,如果你没用看过,请参考Java基础之——泛型(一)这篇我们来讲一下泛型高级之通配符吧!
一、通配符是个什么玩意
简单来说,通配符就是一个 ?,用来代表任意类型。例如:

ArrayList<?> arrayList = new ArrayList<String>();

二、通配符的三种形式

  1. ?
  2. ? extends E
  3. ? super E

第一种 ? 代表 任意类型
比如

//这里的arrayList可以接受任意类型
ArrayList<?> arrayList = new ArrayList<String>();

ArrayList<?> arrayList = new ArrayList<Integer>();

注意,有人可能会说,既然是任意类型,能不能用Object来代替,例如

//错误用法
ArrayList<Object> arrayList = new ArrayList<String>();

这是错误的,因为Java在定义泛型时必须要求 前后一致,如果前面是Object,后面必须是Object,

//正确用法
ArrayList<Object> arrayList = new ArrayList<Object>()

//或者
ArrayList<Object> arrayList = new ArrayList<>();

//Java1.7之后,后面的类型可以不用写,你前面传的啥类型,后面默认就是啥类型

那如果我们想接受任意类型怎么办,java已经替我们想好了,就用 ? 来代替就好了。

第二种 ? extends E 代表 E及其子类
比如

public class Genericity {

    public static void main(String[] args) {

        //这里的类型是Person类,即本身 
        ArrayList<? extends Person> array1 = new ArrayList<Person>();

        //这里的类型 是 Student 类,Persion子类
        ArrayList<? extends Person> array2 = new ArrayList<Student>();


        //报错,因为只能接受 Person本身 或者他的子类
        ArrayList<? extends Person> array3 = new ArrayList<String>();
    }

    //新建一个person,作为父类,
    class Person{

    }
    //新建一个person,作为子类
    class Student extends Person{


    }

}

上面的代码非常简单,我们新建了一个Genericity类,然后再里面又新建了两个内部类,Person(父类)和Student(子类),这里

ArrayList<? extends Person> array1 = new ArrayList<Person>();

? extends Person 的意思就是 只能接受Person类(本身)或者它的子类,其他的类型我不接受。

第三种 ? super E 代表 E及其父类

如果看懂了第二种,第三种也很简单,其实是一模一样的

ArrayList<? super Person> array4 = new ArrayList<Person>();

? super Person 的意思就是 只能接受Person类(本身)或者他的父类,其他的类型我不接受。

下面这种接收的就是它的父类(因为任何类都继承于ObJect)

ArrayList<? super Person> array5 = new ArrayList<Object>();

好了,知识点就这么多,不能总是纸上谈兵,让我们来学以致用吧!

三、实践是最好的老师

1.实践一 通过泛型来简化findViewById
在做安卓开发的时候,我们是不是经常写findViewById了吧,每次都要Cast一下

 Button btn = (Button)findViewById(R.id.btn);

写多了,都有想吐的感觉了,那怎么办呢?
1.可以用注解的方式(ps我没学)
2.用泛型(就是你了)
3….
在BaseActivity(基类)定义如下泛型方法:

public class BaseActivity extends Activity {

//在这个类中定义泛型方法,以后我们写的类都继承BaseActivity,这样就能调用这个方法
    public final <E extends View> E getView (int id) {
        try {
            return (E) findViewById(id);
        } catch (ClassCastException ex) {
            Log.e(TAG, “Could not cast View to concrete class.”, ex);
            throw ex;
        }
    }
}

以上的代码很简单,定义了一个getView方法,返回值是E,也就是是说,调用的时候是什么类型,就返回什么类型,接收类型只能是View及其子类,

使用如下

TextView textView = getView(R.id.textview);
Button button = getView(R.id.button);
ImageView image = getView(R.id.imageview);

是不是感觉很简单,如果想学习更多用法,请参考这篇文章通过泛型来简化findViewById

2.实践二 Android之万能的适配器
这里面也用到泛型,参考这篇博客,张鸿洋大神 万能的适配器
如果不是很懂,可以看他的万能适配器 视频

因为有视频讲解,所以就不多说了!可以自己去分析里面的泛型。
好了,就到这里,have a nice day

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值