复用性:泛型的本质就是参数化类型,于是使用编写的泛型代码能够被许多不一样类型的对象所复用。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());