java5.0新特性泛型将运行时期出现的问题ClassCastException转移到了编译时期,
方便于程序员解决问题,让运行期间问题减少,安全性提高且避免了强制转换的麻烦。
泛型通常在集合框架中很常见,用来限定集合中元素的类型:
如 ArrayList<String> al = new ArrayList<String>();
表示集合al中只能存放String类型的元素。
泛型是给编译器看的,通过反射可以绕过编译器对泛型的检查。
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成。
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
}
public class GenericTest
{
public static void main(String[] args)
{
Utils<Person> ul = new Utils<Person>();
ul.setObject(new Person("ha", 20));
Person p = ul.getObject();
System.out.println(p);
}
}
为了让不同方法可以操作不同类型,而且类型还不确定,可以将泛型定义在方法上,
只有引用类型才能作为泛型方法的实际参数,
静态方法不可以访问类上定义的泛型,如果静态方法类型不确定,可以将泛型定义在方法上。
Class Demo<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
public static <W> void method(W t)
{
System.out.println("method:"+t);
}
}
泛型可定义在接口上:
interface Inter<T>
{
void show(T t);
}
class InterImpl<T> implements Inter<T>
{
public void show(T t)
{
System.out.println("show :"+t);
}
}
泛型的限定:用于泛型扩展
?表示通配符
? extends E:可以接受E类型或者E的子类型,上限。
? super E:可以接受E类型或者E的父类型,下限。
如方法public static void print(Collection<? extends Person> al)
可以打印Person或者是Person类的子类
参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>();//错误
Vector<Object> v = new Vector<String>();//错误
如下方法这样写:
public static void printCollection(Collection<?> collection),
则在方法体中collection不能调用与参数化类型有关的方法
public static void printCollection(Collection<?> collection)
{
System.out.println(collection.size());
for (Object obj : collection)
{
System.out.println(obj);
}
}
类型推断:
private static <T> T add(T x, T y)
{
return null;
}
add(3, 5);
Number x1 = add(3.5, 3);//x1类型取Float和Integer的交集
Object x2 = add(3, "abc");//x2取Integer和String的交集
下面例子交换任意数组指定位置的元素
private static <T> void swap(T[] a, int i, int j)
{
T tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
String[] str = new String[] { "abc", "xyz", "ccc" };
swap(str, 1, 2);
异常泛型举例:
private static <T extends Exception> void run() throws T
{
try{}
catch (Exception e)
{
throw (T) e;
}
}
下面方法将obj对象转换为任意对象:
private static <T> T autoConvert(Object obj)
{
return (T) obj;
}
Object obj = "abc";
String str = autoConvert(obj);
下面方法用任意对象填充任意数组a:
private static <T> void fillArray(T[] a, T obj)
{
for (int i = 0; i < a.length; i++)
{
a[i] = obj;
}
System.out.println(Arrays.toString(a));
}
String[] str = new String[] { "abc", "xyz", "ccc" };
fillArray(str, "ddd"),则数组str中的元素都变成了"ddd".
下面程序将一个数组中的内容拷贝到另一个数组:
public class Generic2<T>
{
private T[] fooArray;
public T[] getFooArray()
{
return fooArray;
}
public void setFooArray(T[] fooArray)
{
this.fooArray = fooArray;
}
public static void main(String[] args)
{
Generic2<String> foo = new Generic2<String>();
String[] str1 = { "hello", "world", "welcome" };
String[] str2 = null;
foo.setFooArray(str1);
str2 = foo.getFooArray();
for (int i = 0; i < str2.length; i++)
{
System.out.println(str2[i]);
}
}
}
好了,对泛型的学习就总结到这了,谢谢。