——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
第一话:泛型概念
概述:
泛型是JDK1.5版本以后出现的新特性,用于解决程序运行时存在的安全隐患。通过“<>”来定义要操作的引用类型。
泛型带来的好处:
1.将运行时期出现的ClassCastException,转移到编译时期,从而提高安全性
2.避免频繁而且麻烦的类型转换。
什么时候使用泛型呢?
“<>”用来接收类型,当使用集合时将集合中要存储的对象类型定义在<>中
弊端:
在一定程度上使得集合的扩展性降低了。
第二话:泛型的运用
泛型类:
当类中要操作引用数据类型不确定时,早期定义Object来完成扩展,现在定义泛型来扩展。
/*泛型出现前用Object来完成工具类的扩展*/
class tools
{
private Object obj;
publci void setObject(Object obj)
{
this.obj = obj;
}
public Objec getObject()
{
teturn obj;
}
}
对象操作该工具时需要类型转换,如果该对象具有Object对象没有的方法,将无法调用Object拥有的方法之外的方法。最致命的是当子类和父类同时使用该工具时,编译可以通过,运行时抛出ClassCastException异常,这使得程序存在隐患。
/*泛型类作为工具*/
class tool<T>
{
private T obj;
public void setObject(T obj)
{
this.obj = obj;
}
public T getObject()
{
return obj;
}
}
/*实例化时需要指定操作类型
tools<String> t = new tools<String>();
*/
泛型类使得当子类和父类同时使用该工具时,编译通不过。而且调用时不需要类型转换。
泛型方法:
泛型类定义的泛型,在整个类中有效。如果要被访问使用,那么泛型类的对象要明确所要操作的具体类型,之后要操作的类型就固定了。为了让不同方法可以操作不同类型,并且类型还不确定,那么可以将泛型定义在方法上。
/*泛型在方法上*/
class Utils<M>
{
public <T> void print(T t)
{
System.out.println("print:"+t);
}
public <T> void show(T q)
{
System.out.println("show:"+q);
}
}
public class gernator
{
public static void main(String[] args)
{
Utils u = new Utils();
u.show("heihei"); //show(String)
u.show(new Utils());//show(Utils对象)
u.print(new Utils());//print(Utils对象)
u.print("heihei");//print(String对象)
}
}
时得类中的方法扩展性大大提升。
特殊之处:
静态方法不可以访问类上定义的类型。
如果静态方法操作的应用数据类型不确定那么可以将泛型定义在方法上。
class Utils<T>
{
//public static void print(T t){}//编译通不过
public static <T> void print(T t){}//正确
}
这是因为泛型只有在建对象的时候才会被定义,而静态在一开始加载类的时候就存在了。所以无法匹配到
泛型限定:
1、?通配符
import java.util.*;
public class fangxing {
public static void main(String[] args)
{
HashSet<String> hs1 = new HashSet<String>();
hs1.add("abc");
hs1.add("abcd");
HashSet<Integer> hs2 = new HashSet<Integer>();
hs2.add(3);
hs2.add(1);
printAll(hs1);
printAll(hs2);
}
//使用?通配符可以实现多个类型对集合的操作,本例为String 和 Integer类型的对象
//如果不用?通配符则需要定义相应类型的比较器,使得代码冗余多
public static void printAll(HashSet<?> hs)
{
for(Iterator<?> it = hs.iterator(); it.hasNext();)
{
System.out.println(it.next());
}
}
}
2.? extends 父类
import java.util.*;
class Base
{
public void print()
{
System.out.println("I Am Base!");
}
}
class Sub1 extends Base
{
public void print()
{
System.out.println("Sub1 show!");
}
}
class Another
{
public void print()
{
System.out.println("Sub2 show!!");
}
}
public class GenericityDemo {
public static void main(String[] args)
{
HashSet<Base> hs_base = new HashSet<Base>();
hs_base.add(new Base());
HashSet<Sub1> hs_sub1 = new HashSet<Sub1>();
hs_sub1.add(new Sub1());
HashSet<Another> hs_an = new HashSet<Another>();
hs_an.add(new Another());
//调用方法
getMethod(hs_base);
getMethod(hs_sub1);
// getMethod(hs_sub2);//报错 因为getMethod()方法已经被限定类型了只能是Base和他的子类才可调用
}
//限定只有Base和他的子类对象才能调用
private static void getMethod(HashSet<? extends Base> hs)
{
for(Iterator<? extends Base> it = hs.iterator(); it.hasNext();)
{
it.next().print();
}
}
}
3.? super 子类
跟? extends 父类 一样的机制。不同点在于父类可以有多个子类,但是子类只有一个父类,但他们可以将对象限定在子对象和他的父对象中。