android 泛型编程

来源:互联网 发布:手机搬家软件 编辑:程序博客网 时间:2024/05/22 06:53

android 泛型编程

泛型
generic type/generics是Java语言的类型系统的一种扩展,支持创建可以按类型进行参数化的类。
泛型的本质是类型的参数化,就是用一个变量来表示类型,如类型参数 T,你可以向其传递String Integer Student(自定义类类型)等具体类型 ,从而实现泛化
把类型参数看作是使用参数化类型时指定的类型的一个占位符,像方法的形参是运行时传递的值的占位符一样

java中泛型的引入主要是为了解决两个方面的问题:
1.集合类型元素在运行期出现类型装换异常,增加编译时类型的检查
2.解决的时重复代码的编写,能够复用算法

类型参数
形式类型参数与实际类型参数之间的关系类似于一般方法的形参与实参之间的关系,只是类型参数表示类型,而不是表示值。
在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数。
泛型类中的类型参数几乎可以用于任何可以使用类名的地方

类型参数命名
推荐的命名约定是使用大写的单个字母名称作为类型参数。对于常见的泛型模式,推荐名称:
T – 泛型
E – 异常类
K – 键,映射的键
V – 值,如List和Set的内容,或者Map中的值
android泛型化,诸如:

标准集合接口Collection<V>、List<V>、Set<V> 和 Map<K,V>。集合接口实现HashMap<K,V>实现Map<K,V>(用相同类型参数泛型化的)

类型擦除
type erasure Java中的泛型基本上都是在编译器层次实现的,使用泛型加上的类型参数,会在编译的时候去掉(生成的Java字节码中是不包含泛型中的类型信息的)。这个过程就称为类型擦除。
(类型擦除也是Java的泛型实现方法与C++模版机制实现方式之间的重要区别)
如:

代码中定义的List<object>List<String>等类型,在编译后都会编程List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。 (比较List<String> arrayList1对象和List<Integer> arrayList2对象的getClass方法(获取对象的类的信息)的返回值 --- arrayList1.getClass()==arrayList2.getClass(),结果为true: 说明泛型类型List<String>List<Integer>都被擦除掉了,只剩下了原始类型List)

泛型的好处
1、类型安全。
通过泛型定义的变量类型限制,编译器可以更有效地提高Java程序的类型安全(编译时的类型安全检查)。
2、消除强制类型转换。
代码更加可读,减少了出错机会
3、提高性能
更多类型信息可用于编译器
4、使用泛型重构代码,可精简程序代码(避免代码冗余)、灵活实现多功能, 诸如RxJava、Okhttp开源框架库中都用广泛应用

泛型使用的注意事项
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
2、泛型的类型参数可以有多个。
3、不能对确切的泛型类型使用instanceof操作。
4、不能创建一个确切的泛型类型的数组,采用通配符的方式是被允许。//JVM泛型的擦除机制
5、不能在静态域或非泛型方法中出现类型参数
6、一个类不能成为两个接口类型(这两个接口是同一接口的不同参数化)的子类,会冲突
//采用通配符的方式适应泛型数组

//List<String>[] lsa = new List<String>[10]; // sun的使用说明文档指出“不能创建一个确切的泛型类型的数组”,数组的类型不可以是一种确切的泛型类型List<?>[] lsa = new List<?>[10]; // OK, array of unbounded wildcard type. ?通配符表示特定的未知类型,   Object o = lsa;    Object[] oa = (Object[]) o; // Object数组List<Integer> li = new ArrayList<Integer>();     li.add(new Integer(3));    oa[1] = li; // Correct.    Integer i = (Integer) lsa[1].get(0); // OK 

Java中的泛型方法
http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html
java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
http://blog.csdn.net/s10461/article/details/53941091

基本的泛型使用:
泛型限定

通过?通配符来实现的,extends, super, ?通配符来对类型参数进行限定*? extends SomeClass  只能接收SomeClass及其子类类型,所谓的“上限”*? super SomeClass 只能接收SomeClass及其父类类型,所谓的“下限”List<?>表示具有某种特定类型的非原生List,?通配符表示未知类型。List实际上表示持有任何Object类型的原生ListList<Object>)//1、泛型接口 --- <T>: 声明泛型, 可为T传入不同类类型的实参,形成不同种类型的Generator接口,如Generator<String> Generator<Student>public interface Generator<T> {    public T test();}//2、泛型类 --- <T>: 声明泛型, 实例化泛型类时,指定T的类型public class Generic<T>{      private T key;    public Generic(T key) { //泛型构造方法        this.key = key;    }    public T getKey(){ //泛型方法        return key;    }       //泛型类中声明一个泛型方法,使用泛型E(泛型E可以为任意类型,可以类型与T相同,也可以不同)    //编译器能够正确识别泛型方法中声明的泛型。    public <V> void testValue(V v){        System.out.println(v.toString());    }       //泛型类中声明一个泛型方法,该方法声明的泛型T与泛型类中声明的T不是同一种类型    public <T> void testType(T t){        System.out.println(t.toString());    }          //静态方法默认不允许使用泛型类中已经声明过的泛型    //需要添加额外的泛型声明<T>, 成为泛型方法后, 才可以在该方法中使用声明的泛型类型T (静态方法要使用泛型,必须将静态方法定义成泛型方法)    public static <T> void show(T t){     }}//限定泛型类,T只能是Number及其子类类型public class Generic<T extends Number>{    ...}//泛型方法中添加上下边界限定,只须在<T>声明上添加上下边界<T extends Number>public <T extends Number> T testKey(Generic<T> obj){    System.out.println("key value:" + obj.getKey());    T test = container.getKey();    return test;}//泛型的类型参数只能是类类型如String Integer Student(自定义类类型),不能是简单类型,传入的实参类型需与泛型的类型参数类型相同,如下: Generic<Integer> genericInteger;//指定的类型参数类型Integer genericInteger = new Generic<Integer>(12345); //实参类型IntegerGeneric generic = new Generic(12345); //泛型类中使用泛型的方法或成员变量定义的类型可以为任何的类型//?和String、Integer都是一种实际的类型,可以把?看成所有类型的父类,是一种真实的类型public void testKey(Generic<?> obj){    System.out.println("key value: " + obj.getKey());}public void testKey(Generic<Integer> obj){    System.out.println("key value: " + obj.getKey());}//3、实现泛型接口的类, 接口未传入泛型实参类型class GeneratorClass<T> implements Generator<T>{    @Override    public T test() {        return null;    }}//4、实现泛型接口的类, 接口传入泛型实参类型Stringclass GeneratorClass implements Generator<String>{    private String type = "String";     @Override    public String test() {        return type;    }}//5、泛型方法://1、public后的<T>:声明了<T>的方法才是泛型方法或声明此方法持有类型T(然后方法就可以使用泛型类型T)//2、Class<T>:指明泛型的具体类型,Class<T>类型变量c,可以用来创建泛型类的对象(Class<T>代表类型T所对应的类)public <T> T getInstance(Class<T> c)throws InstantiationException, IllegalAccessException{   T instance = c.newInstance();   return instance;}public <T> T parseMap(String str, Class<T> c){   T jsonString= JSON.parseObject(str, c);   return jsonString;}Map jsonString = parseMap("map", Map.class);
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 衣服买完降价了怎么办 在淘宝上不发货怎么办 一加3t吃鸡卡怎么办 小米max打游戏反应慢怎么办 小米max2手机玩游戏卡怎么办 魅蓝metal开不了机怎么办 魅蓝e手机信号差怎么办 魅蓝metal手机已锁定怎么办 魅族not3卡开了怎么办 魅族metal手机好卡怎么办 魅蓝手机锁机了怎么办 魅族note2屏坏了怎么办 魅族mx3开不开机怎么办 魅蓝max3充电慢怎么办? 魅族手机home键失灵怎么办 魅族开关键坏了怎么办 魅族开关键不灵怎么办 魅蓝开机键坏了怎么办 魅族开关机坏了怎么办 小米开机键坏了怎么办 魅族手机关机键失灵怎么办 魅蓝5s发热严重怎么办 华为荣耀v8信号差怎么办 贴膜白边去除液漏进屏幕里面怎么办 魅族pro6s电池休眠了怎么办 京东预约错了怎么办 魅蓝手机声音小怎么办 魅族2手机锁定了怎么办 flyme的密码忘了怎么办 魅族note3忘记开机密码怎么办 小米3s手机死机怎么办 二手小米手机有账号锁怎么办 小米五指纹解锁失灵怎么办 小米note3指纹解锁失灵怎么办 小米4s手机屏幕失灵怎么办 vivo手机没有otg功能怎么办 头戴耳机压头发怎么办 小米4c很卡怎么办 小米4c玩王者怎么办 小米4s屏幕乱跳怎么办 小米4s手机后壳碎了怎么办