android 泛型编程

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); //实参类型Integer
Generic 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、实现泛型接口的类, 接口传入泛型实参类型String
class 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);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值