泛型详解

泛型

泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能。

ClassCastExceptions(类型转换异常)
我们来举一个小例子:

package fiftyThird;

import java.util.List;
import java.util.ArrayList;

public class ArrayListTest {

	public static void main(String[] args) {
		List list = new ArrayList();
		
		list.add("string");
		list.add(new Integer(2));
		list.add(new Boolean(false));
		
		String string = (String)list.get(0);
		Integer integer = (Integer)list.get(1);
		String b = (String)list.get(2);

	}

}

结果是:
Exception in thread “main” java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String at fiftyThird.ArrayListTest.main(ArrayListTest.java:17)
看代码,我们知道第三个赋给list的类型是boolean但是我们提取的时候给强转成String所以会抛出异常ClassCastException,因为boolean不能转换为String。

在JDK1.5中,你可以声明一个集合将接收/返回的对象的类型

package fiftyThird;

public class BooleanFoo {

	private Boolean foo;

	public Boolean getFoo() {
		return foo;
	}

	public void setFoo(Boolean foo) {
		this.foo = foo;
	}
	
}

package fiftyThird;

public class IntegerFoo {

	private Integer foo;

	public Integer getFoo() {
		return foo;
	}

	public void setFoo(Integer foo) {
		this.foo = foo;
	}
}

类别定义时的逻辑完全一样,只是里面成员变量的类型不同.

如果需要多个相似的类,需要定义多个文件,不同的只是变量的类别,而逻辑是完全一样的.
对之前代码的一些改写

package fiftyThird;

public class ObjectFoo {

	private Object foo;

	public Object getFoo() {
		return foo;
	}

	public void setFoo(Object foo) {
		this.foo = foo;
	}
	
	public static void main(String[] args) {
		ObjectFoo foo1 = new ObjectFoo();
		ObjectFoo foo2 = new ObjectFoo();
		
		foo1.setFoo(new Boolean(false));
		foo2.setFoo(new Integer(10));
		
		Boolean b = (Boolean)foo1.getFoo();
		Integer i = (Integer)foo2.getFoo();
		
		
		
	}
}

上述代码只能在运行的时候发现是什么类型的,而当我们加入泛型后:

package fiftyThird;

public class GenericFoo<T> {

	private T foo;

	public T getFoo() {
		return foo;
	}

	public void setFoo(T foo) {
		this.foo = foo;
	}
	
	public static void main(String[] args) {
		GenericFoo<Boolean> foo1 = new GenericFoo<Boolean>();
		GenericFoo<Integer> foo2 = new GenericFoo<Integer>();
		
		foo1.setFoo(new Boolean(false));
		foo2.setFoo(new Integer(3));
		Boolean boolean1 = foo1.getFoo();
	    Integer integer = foo2.getFoo();
	    
	    System.out.println(boolean1);
	    System.out.println(integer);
	
	
	}
	
}

我们在编译期间就能发现问题,这里面就是泛型。
在泛型命名时我们一般以单个大写字母表示。
所谓泛型就是变量类型参数化。

foo1 = foo2;

这样就是错误的。

GenericFoo aFoo = new GenericFoo();

当我们定义好泛型后不适用会提示警告:
GenericFoo 是原始类型。应该将对通用类型 GenericFoo 的引用参数化

        aFoo.setFoo("hello");
	    
	    String string = (String)aFoo.getFoo();
	    
	    System.out.println(string);

结果是:
hello

Generic多个泛型实现

package fiftyFourth;

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());
	}
}

结果是:
-20
false

数组的泛型

package fiftyFourth;

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]);
		}

	}

}

结果是:
hello
world
welcome

集合的泛型

自己模仿集合做一个类似的类

package fiftyFourth;

public class SimpleCollection<T> {

	private Object[] objArr;
	private int index = 0;
	
	public SimpleCollection() {
		objArr =  new Object[10];
	}
	
	public SimpleCollection(int capacity) {
		objArr = new Object[capacity];
	}
	
	public void add(T t) {
		objArr[index++] = t;
	}
	
	public int getLength() {
		return this.index;
	}
	
	public T get(int i) {
		return ((T)objArr[i]);
	}
	
	public static void main(String[] args) {
		SimpleCollection<Integer> collection = new SimpleCollection<Integer>();
		
		for(int i = 0; i < 10; i++) {
			collection.add(new Integer(i));
		}

		for(int i = 0; i < 10 ; i++) {
			Integer integer = collection.get(i);
			
			System.out.println(integer);
		}
	}
}

结果是:
0
1
2
3
4
5
6
7
8
9

泛型的泛型

package fiftyFourth;

public class WrapperFoo<T>{
	
	private GenericFoo3<T> foo;

	public GenericFoo3<T> getFoo() {
		return foo;
	}

	public void setFoo(GenericFoo3<T> foo) {
		this.foo = foo;
	}
	public static void main(String[] args) {
		GenericFoo3<Integer> foo3 = new GenericFoo3<Integer>(); 
	
		foo3.setFoo(new Integer(-10));
	
		WrapperFoo<Integer> wrapperFoo = new WrapperFoo<Integer>();
	
		wrapperFoo.setFoo(foo3);
		
		GenericFoo3<Integer> genericFoo3 = wrapperFoo.getFoo();
		
		System.out.println(genericFoo3.getFoo());
	}

}
class GenericFoo3<T>{
	private T foo;
	
	public T getFoo() {
		return foo;
	}
	
	public void setFoo(T foo) {
		this.foo = foo;
	}
}

结果是:
-10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值