前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >泛型学习(一)

泛型学习(一)

作者头像
艳龙
发布2021-12-16 17:36:19
2030
发布2021-12-16 17:36:19
举报
文章被收录于专栏:yanlongli_艳龙yanlongli_艳龙

Android 在日常中经常使用的 List<E>, ArrayList<E> 是我们接触最多的泛型类。 清楚什么是泛型,怎么定义泛型可以帮助我们更好的理解系统中提供的泛型类的结构和用途。

自定义 泛型类与泛型方法

User.java

代码语言:javascript
复制
/**
 *
 * 自定义泛型类:
 * 1,继承的自定义泛型类可以指定泛型类型, 那子类就不再是泛型类了 见 SZUser
 * 2,继承的自定义泛型类也可以不指定类型,继续保持泛型, 见GZUser
 * 3,异常类不能是泛型类
 * 4,泛型类实例化时,若没有指定类型,默认使用Object
 *
 *
 * 泛型方法:
 * 1,在方法中出现泛型结构,泛型参数与类的泛型参数没有任何关系。也就是说泛型方法所属的类是不是泛型类都没有关系。
 * 2,泛型方法在调用时,指明泛型参数的类型
 * 3, 静态方法不可以使用类的泛型
 *
 * @description
 */
public class User<T> {

    String name;

    int id;

    T orderType;

    public User(String userName, int id, T orderType) {
        this.name = userName;
        this.id = id;
        this.orderType = orderType;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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



    //自定义泛型方法
    public <E> List<E> copyFromArrayToList(E[] arr) {
        ArrayList<E> list = new ArrayList<>();
        for (E e: arr) {
            list.add(e);
        }
        return list;
    }


    // 如下的3个方法都不是泛型方法
    public T getOrderType() {
        return orderType;
    }

    public void setOrderType(T orderType) {
        this.orderType = orderType;
    }

    @NonNull
    @Override
    public String toString() {
        return "{name = " + name + ", id = " + id + ", orderType = " + orderType.toString() + "}";
    }
}

SZUser.java

代码语言:javascript
复制
public class SZUser extends User<Integer> {
    public SZUser(String userName, int id, Integer orderType) {
        super(userName, id, orderType);
    }
}

GZUser.java

代码语言:javascript
复制
public class GZUser<T> extends User<T> {
    public GZUser(String userName, int id, T orderType) {
        super(userName, id, orderType);
    }
}

自定义泛型接口和自定义泛型类基本类似:

Show.java

代码语言:javascript
复制
public interface Show<T, U> {
    void show(T t, U u);
}

ShowTest.java

代码语言:javascript
复制
public class ShowTest implements Show<String, Integer> {
    @Override
    public void show(String s, Integer integer) {
              // testPrint("---------")
    }
}

泛型变量的类型限定

上面自定义的泛型中,没有对泛型<T>有任何的限制。在实际的开发过程中,有很多的场景需要对泛型进行一定的限制。 具体见如下demo:

Utils.java

代码语言:javascript
复制
public class Utils {
    public static <E extends Comparable> int compareTo(E e1, E e2) {
        return e1.compareTo(e2);
    }
    

     public static <E extends SuperActivity & Comparable & Serializable> int compareTo(E e1, E e2) {
        return e1.compareTo(e2);
    }
}

tips: 类型限定在泛型类、泛型接口和泛型方法中都可以使用,不过要注意下面几点:

  • 泛型限定 , 在类/接口/方法中,统一都使用关键字 extends
  • 如果限定既有接口也有类,那么类必须只有一个(类是单继承的),并且放在首位置

泛型通配符

代码语言:javascript
复制
    public void test() {
        //声明
        List<?> list = new ArrayList<Integer>();
        list = new ArrayList<String>();
        list = new ArrayList<Object>();
        
        Object o = list.get(0); //编译通过
        list.add(new A());      //编译不通过
        list.add(new B());      //编译不通过
        list.add(new C());      //编译不通过
        list.add(new D());      //编译不通过

        test(list);
    }

    public static void test(List<?> list){

    }

tips:

  • 无边界通配符 ? 能取不能存。这个好理解,因为编译器不知道?具体是啥类型,故不能存;但是任意类型都继承于Object,故能取,但取出默认为Object对象。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/2/26 上,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自定义 泛型类与泛型方法
  • 泛型变量的类型限定
  • 泛型通配符
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档