分类: Java
2009-11-27 16:02:42
写完两个笔记,才发现才只写到官方文档的第7节~一共11节~
我非常吐血。
Collection cs = new ArrayList
if (cs instanceof Collection
这个是错误的,因为上个笔记讲过所有泛型类的getClass都是一样的。
所以通常问它的instanceof是没有意义的。原文如下:
Another implication of the fact that a generic class is shared among all its instances,
is that it usually makes no sense to ask an instance if it is an instance of a particular
invocation of a generic type
而且如果要强制转换:
Collection
会出现警告,其实这个道理上两个笔记讲了n遍了。。
有个例子
}
这个有警告,一个道理。
到现在为止,Java泛型都是用在容器里的,比如
Collection extends Shape> shapechildren;
或者void drawAll(Collection extends Shap> shapchilren) { ... }
但是java泛型不是只能用在容器里。
java泛型用在容器里比较让人容易理解,因为Collection
这个容器里的每个元素都是T类型,T可以替换。
List extends Shape> listshape;就表示Shape类的子类的集合。
在另外一个特殊的类中,泛型也有广泛的高级应用。
那就是java.lang.Class
这个类在jdk1.5之前没有
例子场景:
从数据库里读取n个对象,然后放入一个容器。
比如读取一个厂里的工作人员的信息:
第一个版本:可以这样写:
interface Factory
public
Collection
//运行sql语句
for(//遍历ResultSet) {
T item = factory.make();
//利用反射填入对象T
result.add(item);
}
return result;
}
那么第一个版本有两个缺点:
1.使用不方便。
2.代码不重用。
为什么使用不方便?
我们使用这段代码只有两种方式:
select(new Factory
public EmplInfo make() {
return new EmplInfo();
}
}, "sql语句");
还一种方式:
class EmplInfoFactory implements Factory
...
public EmplInfo make() {
return new EmplInfo();
}
}
然后
EmplInfoFactory emplfactory = new EmplInfoFactory();
select(emplfactory, "sql语句");
其实大家都知道,上面两个方法的本质是一样的,都是要首次建立一个实现类。
从这一点上说,使用不方便。
为什么不重用?
上个例子中我是需要EmplInfo这个对象的容器,但是如果我需要这个厂里的
Manager的容器的时候,就需要重写代码,如下:
class ManaInfoFactory implements Factory
...
public ManaInfomake() {
return new ManaInfo();
}
}
然后
ManaInfoFactory manafactory = new ManaInfoFactory();
select(manafactory, "sql语句");
从这里可以看出代码不重用。因为我需要另外一个实现类。
以上方法发生在没有使用泛型,也没有使用java.lang.Class的时代
那么使用上了java.lang.Class会是什么样呢?
如果我们使用了jdk1.5之前的java.lang.Class,那么以上两个缺点就解决了,
当然会引入新的缺点,最终由jdk1.5中的java.lang.Class
Collection emps = sqlUtility.select(EmpInfo.class, ”select * from emps”); //这是调用句
public static Collection select(Class c, String sqlStatement) {
Collection result = new ArrayList();
/* run sql query using jdbc */
for ( /* iterate over jdbc results */ ) {
Object item = c.newInstance();
/* use reflection and set all of item’s fields from sql results */
result.add(item);
}
return result;
}
这段代码解决了
1.使用不方便,因为不需要建立实现类
2.代码不重用,因为如果要ManaInfo的话,可以这样使用,Collection mana = sqlUtility.select(ManaInfo.class, ”select * from mana”)
这段代码引入了一个问题:
返回值是Collection并且最终赋值给了Collection.
这个做法前面几个笔记讲了n遍了,会引起警告,因为Collection是可以加入任何元素的。不仅仅是EmplInfo
所以最终解决方案,使用jdk1.5中引入的java.lang.Class
Collection
public static
Collection
/* run sql query using jdbc */
for ( /* iterate over jdbc results */ ) {
T item = c.newInstance();
/* use reflection and set all of item’s fields from sql results */
result.add(item);
}
return result;
}
到此,Class