----------android培训、java培训期待与您交流!----------
泛型的基本应用
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据。例如:用反射得到集合,再调用其add方法即可。泛型可以解决数据类型的安全性,其主要原理是类在申明时通过一个标识表示类中某个属性或者是某个方法的返回值及参数类型
泛型类定义
访问权限 class类名称 <泛型标识符1,泛型标识符2,。。。>{
访问权限泛型类型标识符变量名称;
访问权限泛型类型标识符方法名称(){};
访问权限 返回值类型声明方法名称(泛型类型标识符变量名称)
}
泛型对象定义
类名称<具体类>对象名称 = new 类名称<具体类>();
实例代码--声明泛型
class Point<T>{ //此处可以随便写标识符号,T是type的简称
private T var ; // var 的类型由T指定,即:由外部指定
public T getVar(){ //返回值的类型由外部决定
return var ;
}
public void setVar(T var){ // 设置的类型也由外部决定
this.var = var ;
}
};
public class Demo{
public static void main(String args[]){
Point<String>p = new Point<String>(); //里面的var类型为String类型
p.setVar( "hello") ; //设置字符串
System. out.println(p.getVar().length()); //取得字符串的长度
}
};
结果:5
PS:上述泛型的限制中,设置的是String类型。要注意,在泛型的指定中是无法指定基本数据类型的,必须设置成一个类,这样在设置一个数字时,就必须使用包装类。加入泛型最大的好处实际上就是避免了类型转换异常,这样将使程序的操作更加安全。
泛型应用中的构造方法
访问权限构造方法([<泛型类型>参数名称]){
}
class Point<T>{ //此处可以随便写标识符号,T是type的简称
private T var ; // var 的类型由T指定,即:由外部指定
public Point(Tvar){ //通过构造方法设置内容
this.var = var ;
}
public T getVar(){ //返回值的类型由外部决定
return var ;
}
public void setVar(T var){ // 设置的类型也由外部决定
this.var = var ;
}
};
public class Demo{
public static void main(String args[]){
Point<String>p = new Point<String>("hello" ) ; // 里面的var类型为String类型
System. out.println("内容:" + p.getVar()) ;
}
};
结果:内容:hello
ps:即便有泛型声明,也只是在类的定义上声明,而与构造方法的定义无关
指定多个泛型类型
如果一个类中有多个属性需要使用不同的泛型声明,则可以在声明类时指定多个泛型
代码实例-设置多个泛型类型
class Notepad<K,V>{ //此处指定了两个泛型类型
private K key ; //此变量的类型由外部决定
private V value ; //此变量的类型由外部决定
public K getKey(){
return this .key ;
}
public V getValue(){
return this .value ;
}
public void setKey(K key){
this.key = key ;
}
public void setValue(V value){
this.value = value ;
}
};
public class Demo{
public static void main(String args[]){
Notepad<String,Integer>t = null ; //定义两个泛型类型的对象
t= new Notepad<String,Integer>(); //里面的key为String,value为Integer
t.setKey( "hello") ; //设置第一个内容
t.setValue(30); //设置第二个内容
System. out.print("姓名;" + t.getKey()); // 取得信息
System. out.print(",年龄;" + t.getValue()); // 取得信息
}
};
结果:姓名;hello,年龄;30
泛型的安全警告
在泛型应用中最好在声明类对象时就指定好奇内部的数据类型,如Info<String>,如果不指定类型,这样在指定使用时,就会出现不安全的警告
通配符
在泛型操作中,可以通过通配符接收任意指定泛型类型的对象。
匹配任意对象的引用传递时最常见的,但是在泛型的操作中,在进行引用传递时泛型类型必须匹配才可以使用
受限泛型
在引用操作传递中,在泛型操作中也可以设置一个泛型对象的范围上限和范围下限。范围上限使用extends关键字声明,表示参数化的类型可能是所指定的类型或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型,或者是此类型那个的父类型,或者是Object类
代码实例-泛型的上限
设置方法只能接收泛型为Number或Number类型的子类
class Info<T>{
private T var ; //定义泛型变量
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this .var ;
}
public String toString(){ //直接打印
return this .var .toString() ;
}
};
public class Demo{
public static void main(String args[]){
Info<Integer>i1 = new Info<Integer>(); //声明Integer的泛型对象
Info<Float>i2 = new Info<Float>(); //声明Float的泛型对象
i1.setVar(30); //设置整数,自动装箱
i2.setVar(30.1f); //设置小数,自动装箱
fun(i1);
fun(i2);
}
public static void fun(Info<? extends Number> temp){ // 只能接收Number及其Number的子类
System. out.print(temp + "、" ) ;
}
};
结果:30、30.1、
泛型的下限
class Info<T>{
private T var ; //定义泛型变量
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this .var ;
}
public String toString(){ //直接打印
return this .var .toString() ;
}
};
public class Demo{
public static void main(String args[]){
Info<String>i1 = new Info<String>(); //声明String的泛型对象
Info<Object>i2 = new Info<Object>() ; //声明Object的泛型对象
i1.setVar( "hello") ;
i2.setVar( new Object()) ;
fun(i1);
fun(i2);
}
public static void fun(Info<? super String> temp){ // 只能接收String或Object类型的泛型
System. out.print(temp + "、" ) ;
}
};
结果:
hello、java.lang.Object@459189e1、
小结:
1 泛型可以是程序的操作更加安全,可以避免发生类转换异常
2 在程序中如果使用类没有指定泛型,将使用Object接收参数
3 通过<? extends类>可以设置泛型的上限,通过<? super类>可以设置泛型的下限