所谓泛型:就是变量类型的参数化。
泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能。
•在JDK1.5中,你可以声明一个集合将接收/返回的对象的类型
如果使用泛型,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException
public class Generic<T1, T2>
{
private T1 foo1;
private T2 foo2;
public T1 getFoo1()
{
return foo1;
}
public void setFoo1(T1 foo1)
{
this.foo1 = foo1;
}
public T2 getFoo2()
{
return foo2;
}
public void setFoo2(T2 foo2)
{
this.foo2 = foo2;
}
public static void main(String[] args)
{
Generic<Integer, Boolean> foo = new Generic<Integer, Boolean>();
foo.setFoo1(new Integer(-20));
foo.setFoo2(new Boolean(false));
System.out.println(foo.getFoo1());
System.out.println(foo.getFoo2());
}
<p>
</p>}
泛型定义简单数组
public class SimpleCollection<T>
{
private T[] objArr;
private int index = 0;
public SimpleCollection()
{
objArr = (T[])new Object[10];
}
public SimpleCollection(int capacity)
{
objArr = (T[])new Object[capacity];
}
public void add(T t)
{
objArr[index++] = t;
}
public int getLength()
{
return this.index;
}
public T get(int i)
{
return objArr[i];
}
public static void main(String[] args)
{
SimpleCollection<Integer> c = new SimpleCollection<Integer>();
for(int i = 0; i < 10; i++)
{
c.add(new Integer(i));
}
for(int i = 0; i < 10; i++)
{
Integer in = c.get(i);
System.out.println(in);
}
}
}
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
for(int i = 0; i < list.size(); i++)
{
String value = list.get(i);
System.out.println(value);
}
for(Iterator<String> iter = list.iterator(); iter.hasNext();)
{
String value = iter.next();
System.out.println(value);
}
在定义泛型类别时,预设可以使用任何的类型来实例化泛型类型中的类型,但是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口
public class ListGenericFoo<T extends List>
{
private T[] fooArray;
public T[] getFooArray()
{
return fooArray;
}
public void setFooArray(T[] fooArray)
{
this.fooArray = fooArray;
}
public static void main(String[] args)
{
ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>();
ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>();
LinkedList[] linkedList = new LinkedList[10];
foo1.setFooArray(linkedList);
ArrayList[] arrayList = new ArrayList[10];
foo2.setFooArray(arrayList);
//ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>();
}
当没有指定泛型继承的类型或接口时,默认使用T extends Object,所以默认情况下任何类型都可以作为参数传入
public class ListGenericFoo<T extends List>
{
private T[] fooArray;
public T[] getFooArray()
{
return fooArray;
}
public void setFooArray(T[] fooArray)
{
this.fooArray = fooArray;
}
public static void main(String[] args)
{
ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>();
ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>();
LinkedList[] linkedList = new LinkedList[10];
foo1.setFooArray(linkedList);
ArrayList[] arrayList = new ArrayList[10];
foo2.setFooArray(arrayList);
//ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>();
}
类型通配说明:
現在您有這麼一個需求,您希望有一個參考名称foo可以接受所有下面的实例
•foo = new GenericFoo<ArrayList>(); foo = new GenericFoo<LinkedList>();
•简单的说,实例化类型持有者时,它必須是实现List的类别或其子类别,要定义这样一个名称,您可以使用 ‘?’ 通配字元,并使用“extends”关键字限定类型持有者的型态
public class GenericTest<T>
{
private T paramA;
public T getParamA()
{
return paramA;
}
public void setParamA(T paramA)
{
this.paramA = paramA;
}
public static void main(String[] args)
{
GenericTest<?extends List> genericTest=null;
genericTest=new GenericTest<ArrayList>();
genericTest=new GenericTest<LinkedList>();
}
}
使用<?>或是<? extends SomeClass>的声明方式,意味著您只能通过该名称來取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的話,那么您就得記得取回的实例是什么类型,然后转换为原來的类型方可进行操作,这就失去了使用泛型的意义。
public class GenericTest<T>
{
private T paramA;
public T getParamA()
{
return paramA;
}
public void setParamA(T paramA)
{
this.paramA = paramA;
}
public static void main(String[] args)
{
GenericTest<String> genericTest=new GenericTest<String>();
GenericTest<? extends Object> genericTest2=genericTest;
genericTest2.setParamA("");//出错
}
}