本文主要是介绍集合-Generic,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
当集合中存储的数据类型不同时,可能会导致程序运行的时候转型异常。
2、 package CollectionDemo;
3、
4、 import java.util.ArrayList;
5、 import java.util.Iterator;
6、 import java.util.List;
7、
8、 public class Demo {
9、
10、 public static void main(String[] args) {
11、 List<Integer> list=new ArrayList<Integer>();
12、 list.add(1);
13、 list.add(2);
14、 list.add(3);
15、 //编译时报错
16、 //list.add("adf");
17、 System.out.println(list);
18、 Iterator<Integer> it=list.iterator();
19、 while(it.hasNext())
20、 {
21、 System.out.println(it.next());
22、 }
23、 }
24、 }
当加上对类型的限制以后,将运行时的异常提前至编译时发生。获取元素的时候无需强转类型,就避免了类型转换的异常问题。
当类中操作的引用数据类型不确定的时候,就可以使用泛型类。注:<>中的数据类型必须是引用类型。
泛型
泛型方法
当写一个函数,调用者传递什么类型的变量,该函数就返回什么类型的变量的时候,因为无法确定传递什么类型的数据,如果不用泛型的话,方法的形参就定义为Object类型,返回值也就是Object类型,但是使用该函数时需要强制类型转换。但是强制类型转换如果每次都判断是什么类型的,然后转换的话执行效率很低,否则可能因为类型不一致而报类型转换异常。所以此时,可以考虑泛型方法。
泛型就是将类型当做变量处理,规范泛型的定义一般是一个大写的任意字母。
函数上的泛型定义方法
public<泛型的声明> 返回值类型函数名(泛型变量名){}
package CollectionDemo;import java.util.ArrayList;
import java.util.List;public class Demo {public static void main(String[] args) {List<Integer> list=new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);System.out.println(new Demo().getData(list));}public <T> T getData(T data){return data;}
}
注:使用泛型方法前需要进行泛型声明,该声明位置在static后,返回值类型前。
泛型类
当一个类中有多个函数声明了泛型,那么该泛型的生命可以声明在类上。
格式:
修饰符 class 类名<泛型>{}
package CollectionDemo;
import java.util.ArrayList;
import java.util.List;public class Demo<T> {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);System.out.println(new Demo().getData(list));}public T getData(T data) {return data;}
}
注:静态方法不可以使用类中定义的泛型
因为类中的泛型需要在对象初始化时指定具体的类型,而静态优先于对象存在,那么类中的静态方法就需要单独进行泛型声明。
package CollectionDemo;import java.util.ArrayList;
import java.util.List;public class Demo<T> {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);System.out.println(Demo.getData2(list));}public T getData(T data) {return data;}public static<E> E getData2(E data){return data;}
}
继承泛型类的写法
class Parent<T>
{public T getData(T t){return t;}
}
//父类指定了具体的类型,则子类不用再指定类型
class Child extends Parent<String>
{
}
//当父类使用了泛型,则子类也需要使用泛型
class Child<T> extends Parent<T>
{
}
//错误写法,当父类上定义了泛型,则子类上也需要定义,这里子类没有定义,所以编译出错
class Child extends Parent<T>
{
}
泛型接口
interface Parent<T>{
}//父类定义了明确的类型时
class Child implements Parent<String>{
}//实现不知为何种类型时可以这样定义
class Child2<T> implements Parent<T>{
}
泛型通配符
package CollectionDemo;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;public class Demo {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);//下面这行代码编译不通过new Demo().getData(list);}public void getData(Collection<Object> data) {System.out.println(data);}
}
看上面的代码,getData中对集合限定了为Object类型,而list为Integer类型,所以编译不通过。此时可以通过将List<Integer> list = new ArrayList<Integer>();中的<Integer>去掉,或者将
getData(Collection<Object> data)改为getData(Objectdata),当然,也可以使用泛型通配符来解决。
将getData(Collection<Object> data)改为getData(Collection<?>data)
可以对类型进行限定范围
? extends E :接收E类型或者E类型的子类型
? super E :接收E类型或者E的福类型
接收Number类型或者Number的子类型
正确: List<? extends Number> x=new List<Integer>();
错误: List<? extends Number> x=newList<String>();接收Integer或者Integer的父类型
正确:List<? super Integer> x=new List<Number>();
错误:List<? super Integer> x=newList<Byte>();注:通过泛型,可以将原来程序运行时可能发生的问题,转变为编译时的问题,提高了程序的可读性和稳定性。泛型是提供给编译器使用的,用于限定集合的输入类型,让代码在编译过程中就把错误暴露出来。当编译器编译完带有泛型的程序后,生成的class文件中将不再带有泛型信息,来使程序运行效率不受影响,这个过程称为“擦除”。
这篇关于集合-Generic的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!