複用性:泛型的本質就是參數化類型,於是使用編寫的泛型代碼能夠被許多不一樣類型的對象所複用。java
安全性:在對類型Object引用的參數操做時,每每須要進行顯式的強制類型轉換。這種強制類型轉換須要在運行時才能被發現是否轉換異常,經過引入泛型能將在運行時才能檢查類型轉換,提早到編譯時期就能檢查。數組
java中自定義泛型分爲三種:泛型類、泛型接口、泛型方法。安全
下面使用一個案例演示泛型類、泛型方法,泛型接口相似,因此再也不演示。app
// 自定義泛型類
public class Generic<T>
{
private T second;
public void setSecond(T newValue)
{
second = newValue;
}
// 自定義泛型方法
public static <W> void printValue(W obj)
{
System.out.println(obj.toString());
}
@Override
public String toString()
{
return second.toString();
}
public static void main(String[] args)
{
//
Generic<String> g = new Generic<String>();
g.setSecond("zhang");
System.out.println(g);
// 使用泛型方法
Generic.printValue(45);
Generic.printValue("hello");
}
}
public static void main(String[] args)
{
ArrayList<String> arrayList1=new ArrayList<String>();
arrayList1.add("abc");
ArrayList<Double> arrayList2=new ArrayList<Double>();
arrayList2.add(666.666);
System.out.println(arrayList1.getClass()==arrayList2.getClass());
}
trueide
public static void main(String[] args)
{
ArrayList<String> arrayList1=new ArrayList<String>();
arrayList1.add("abc");
String str = arrayList1.get(0); // 編譯正常
int str2 = arrayList1.get(0); // 編譯報錯
}
public static void main(String[] args)
{
List<? extends Animate> animates = new ArrayList<Animate>(); // OK
List<? extends Animate> animates1 = new ArrayList<Cat>(); // OK
List<Animate> animates2 = new ArrayList<Animate>(); // OK
List<Animate> animates3 = new ArrayList<Cat>(); // compile-time error
}
List<? extends Animal> animal = new ArrayList<>();上面的兩個add操做都不能經過編譯。爲何呢?因爲List:add(E e)加入泛型變成List<? extends Animal>:add(? extends Animal e),? extends Animal參數類型沒法肯定,能夠是Animal、Cat等,因此爲了保護其類型的一致性,所以不容許向list對象中添加任意對象,除了null。
animal.add(new Animal());
animal.add(new Cat());
List<? super Animate> animates = new ArrayList<>();
animates.add(new Animate());
animates.add(new Cat());