Java基础再学习之泛型_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java基础再学习之泛型

Java基础再学习之泛型

 2011/1/14 7:38:55  xielingjiang  http://xielingjiang.javaeye.com  我要评论(0)
  • 摘要:泛型在jdk1.5出来的,以为自己很理解它了,至少看看代码,写写基本的没有问题。由于是个新事物,对于我这种从jdk1.1过来的人来说还是一个思维上的跳跃。最近写了一些代码,好好整理了一下。为什么会出现泛型我喜欢事事问为什么,要不然就觉得心里不踏实。我已经不止一次的提到过,任何的新技术的出现都是伴随着解决一个问题来的。那泛型解决了什么?我们记得在以前的编码过程中,exception中无非就那几种是比较常见和头疼的。第一大非NullPointerException莫属了,我就不多说了
  • 标签:学习 Java 泛型
泛型在jdk1.5出来的,以为自己很理解它了,至少看看代码,写写基本的没有问题。
由于是个新事物,对于我这种从jdk1.1过来的人来说还是一个思维上的跳跃。最近写了一些代码,好好整理了一下。
为什么会出现泛型
我喜欢事事问为什么,要不然就觉得心里不踏实。
我已经不止一次的提到过,任何的新技术的出现都是伴随着解决一个问题来的。
那泛型解决了什么?
我们记得在以前的编码过程中,exception中无非就那几种是比较常见和头疼的。第一大非NullPointerException莫属了,我就不多说了,接着就是ClassCastException,因为我们的代码中往往为了所谓的扩展性(可能是过度设计产生的),用了很多Object类作为参数输入,没有泛型之前,我们的处理方法是到处用强制转换,如果保险点就加很多的instanceof.所以这个Class类型匹配要多烦有多烦。
好了,泛型来了,它的最大特点就是要规范你的编码风格,不允许你乱定义你的类型,用错了就编译不过,不用就给你一个警告,哈哈。
总之,泛型的作用就是使代码得到的信号类型一致,从而使行为一致。
怎么要使用泛型
泛型分为两步:申明 + 使用
申明:两个个地方可以申明,类定义中申明,方法定义申明。(有人提出三个地方,接口定义,但是我想接口也是类嘛)
为什么就这两个地方?有什么好处?
如下类定义中申明了一个T类型,这样就可以在这个类中的任何地方用这个T作为类型,就像一辆车,框架有了,但是什么材料做的不知道,可以是铁的,也可以是铝的,所以我们就用”材料T“
来代替材料类型。
public class Car<T extends Metal>{}

那怎么使用这个材料T泛型呢?如果我们new Car的时候不指定材料T的具体,是无法造出汽车的,巧妇难为无米之炊啊。所以我们使用泛型的时候就需要具体化它。
	public class Fe extends Metal{}
	public class Al extends Metal{}

Car<Fe> car1=new Car<Fe>();
Car<Al> car2=new Car<Al>();


这样车车就造出来了,很酷吧?
但是上述有个不爽的地方就是,每次造车的时候必须告诉它是什么材质的,但是有时候我们根本不关心材质的情况下,就显得多余了。比如我要知道每一种车的颜色而不是材质。如果我们按照上述的类申明的泛型,那么可以在class定义后面加个颜色S的泛型(支持逗号),但是如果下次不要颜色,要尺寸,我是不是还要加个尺寸泛型M?
是不是很多啊,所以我想除了一些基本的类型外,其他局部的特性就不用放在类申明里面了,可以放在方法申明里面,怎么做呢?请看
public  class Car{
		public <S extends Color> S getColor(){	
		}
		public <S extends Color> void setColor(S s){
		}
	}

其中的S是专属于方法的,这个方法还可以是static的。
那怎么使用呢?很简单,如下:
	public class Red extends Color{}

Car car3=new Car();
car3.setColor(new Red());


核心思想
说了这么多,我想泛型的核心思想就是规范类和方法的行为。只要两个类或者方法有相同的逻辑,哪怕是一点点相像的地方,我们都可以用一个泛型定义来申明它,这样就使得代码十分简洁安全。
在这里我要提一下复杂关系情况下的泛型。因为任何技术总是原理简单,到复杂环境下就丧失理智,摸不着头脑。
举个例子:父母--子女--性别
父母有子女,子女有性别
如果不用泛型,我们会分别对男孩,女孩分别写逻辑和类。
比如:
public static class Gender{}
	public static class Male extends Gender{}
	public static class Female extends Gender{}
	public static class Child{
		public Gender gender;
	}
	public static class Boy extends Child{}
	public static class Girl extends Child{}
	public static class Father{
		private Child child;
		public Boy getBoy(){
			return (Boy) child;
		}
		public Girl getGirl(){
			return (Girl) child;
		}
		public void setBoy(Boy boy){
			this.child=boy;
		}
		public void setGirl(Girl girl){
			this.child=girl;
		}
		
	}

是不是觉得两个get/set方法结构一样,但是非要实现,而且方法名字必须不一样,因为类重载不能以返回值来区分。
如果用泛型,就简单清晰了。
首先申明:
public interface Child<G> {}

指定child,但是性别不知道,所以用了“性别G”来代替
接着
public class Father<C extends Child<?>>  {

	private List<C> children = new ArrayList<C>();
	public void addChild(C c) {
		this.children.add(c);
	}
	public List<C> getChildren() {
		return this.children;
	}
}

指定了father,但是不知道子女是男孩还是女孩,所以用了"孩子C"来代替,并且extends Child,意思是至少我知道是个孩子,孩子里面还有个?号,意思是我知道是个孩子,但是我不知道孩子是男是女。
好了,申明好了,接着我们就开始用了。
 		Father<Boy> father1=new Father<Boy>();
		Father<Girl> father2=new Father<Girl>();
		father1.addChild(new Boy());
		father2.addChild(new Girl());


是不是很简洁?
这就是面向对象语言的魅力。
发表评论
用户名: 匿名