黑马程序员_泛型(Generic)
来源:互联网 发布:python urllib 编辑:程序博客网 时间:2024/06/11 08:09
---------------android培训、java培训、期待与您交流! --------------
一,泛型的基础知识
jdk1.5之后出现的新特性
泛型是提供给javac编译器使用的,它可以限定集合中输入的类型,让编译器挡住源程序中的非法输入,编译器编译带类型的说明的集合时会去除掉"类型"信息,是程序运行效率不受影响。对应参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据。例如用反射得到的集合,再调用add方法即可。
泛型是编译器看的,所以通过反射可以避过编译器,继续把不同的类型的值放进已经被泛型限定了的集合里面。
以ArrayList<E>为例
ArrayList称为原始类型,<>译为"typeof",ArrayList<E>称为泛型类型,E称为类型变量或者类型参数;
ArrayList<String>称为参数化的类型,String称为类型参数的实例或实际类型参数
为什么在创建数组实例时,数组的元素不能使用参数化的类型?
编译器是严格按照步骤走的。它检测每一行代码的信息是否有误,但是不会用执行时候的答案来检测代码的正确性。
二,泛型限定:
泛型的通配符(?)应用:?表示任意类型。比如当要定义一个任意参数化类型的集合(Collection<?>
使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。比如集合中的add()方法,使用了?的集合就不能在调用这个方法。
public
也就是说Collection<?>
泛型的限定:
?extends
?super
三,自定义泛型
要定义一个泛型,必须在函数的返回值之前用尖括号括起来
1、//这样声明的范型可以代替任意类型数据我们市场用到的键值对Map.Entry<K,V>不就是给予范型的吗
KV都可以代替任意类型的值,但是在java中范型的实际类型必须是引用类型
<K,V> void get(K k,V v)
{
}
2、Java中的范型不能像C++那么灵活
<T> T add(T a,T b)
{
//return a+b ;//很多人以为java也想C++一样可以这样 ,但是不可以 。
return null;
}
这个返回的null也是有类型限制的,比如上面的ab分别是Integer和String那么就会取他们共同的基类Object做为返回值类型,其他的同理
3、实现任意类型的数组的成员值的交换,注意在自定义范型中范型的实际类型只能是引用数据类型不能是基本数据类型
public static <T> void swap(T[]a,int x,int y)
{
T tem =a[x] ;
a[x]=a[y] ;
a[y]=tem ;
}
上面这个方法如果我 swap(new Integer[]{1,2,3,4,5},1,2); //这样就会自动交换下标12的值
但是这样调用就错了 swao(new int[]{1,2,3,5,6},2,3) ; //所以说Java的范型的实际类型 只能是引用数据类型
4、<T extends String> 表示类型只能是String或者String的派生类
<T super String > 表示范型类型只能是String或者String的父类
用法同3
5、下面这个函数利用范型来实现类型自动转换的功能
public static <T> T autoConvert(Object obj) //因为返回值是 T标识任意类型 所哟可以 将返回结果赋值给任意类型对象
{
return (T)obj;
}
Object obj==”";
String str=autoConvert(obj);
可以完成自动转换,因为范型T代表任意类型,因此他可以赋值给String类型的对象
6、将任意类型的对象填充到任意类型的数组中,与是fillArray(newInteger[]{2,3,4},”ddd”);这样调用是正确的,这样做忽略类型限制
public static <T> void fillArray(T[] a,T b) //将任意一个对象填充到任意类型的数组
{
for(int i =0;i<a.length;i++)
{
a[i] =b ;
}
}
7、以自定义范型的形式显示一个集合的数据,下面一个是利用自定义范型一个是利用通配符来实现,但是不同的是利用通配符操作的集合不能向集合中插入元素。
但是自定义范型却可以。原因是通配符代表的集合我们不知道集合内部具体元素是什么类型所以不能对集合进行add操作。
public static <T> void showCollection(Collection<T> col,T obj) //利用范型来输出任意类型集合
{
col.add(obj) ;
for(T a:col)
{
System.out.println(a);
}
}
public static void showCollection(Collection<?> col) //利用范型来输出任意类型集合
{
for(Object obj:col)
{
System.out.println(obj);
}
}
8、如果一个类中多个方法都需要范型那么就是用类级别的范型。例如
class A<E>
{
public void add(E obj){}
public E get(){}
private E data;
}
这样声明范型和在函数前面声明其实是一样的只不过是在类的级别上作用于整个类而已
9、要注意范型只是给编译器看的。
也就是说Vector<Integer>Vector<String>他们用到的都是同一份字节码,字节码只有class文件加载到内存中的时候才有
所以在一个类中下面2个方法不能同时存在
void show(Vector<Integer>) {}
void show(Vector<String>){}
四,通过反射获得泛型的参数化类型
jdk1.5开始,一个方法可以通过反射获取到他的参数的参数化类型比如:put(Vector<Date>
1.Method里面的方法:
Type[]
Type
2.Type是接口,是ParameterizedType的父类
3.ParameterizedType
Type[]
Type
Type
---------------------- android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima
- 黑马程序员_泛型(Generic)
- 黑马程序员_泛型(Generic)
- 黑马程序员----泛型(Generic)
- 黑马程序员-泛型Generic
- 黑马程序员:Generic泛型
- 黑马程序员_Java_泛型(Generic)
- 黑马程序员-->Java基础加强-->泛型(Generic)
- 黑马程序员—高新技术:泛型Generic
- 黑马程序员——泛型(Generic)
- 黑马程序员-Generic
- 黑马程序员_泛型
- 黑马程序员_泛型
- 黑马程序员_泛型
- 黑马程序员_泛型
- 黑马程序员_泛型
- 黑马程序员_泛型
- 黑马程序员_泛型
- 黑马程序员_泛型
- 用递归方法求和。
- PreTranslateMessage作用和使用方法
- 【Tech-Android-Other】Java内存管理
- 可Wine应用不完全列表
- java web工程中获取根目录的方法
- 黑马程序员_泛型(Generic)
- FTP服务器的搭建
- Java实现两个字符串的比较
- UVa 623 - 500!
- 10000内的回文素数
- 【Android Advanced Training - 03】高效地显示Bitmap图片 [ Lesson 0 - 章节概览 ]
- C#学习笔记-垃圾回收机制
- libcorejni-issue.txt
- 用起泡法对10个数排序。