java代码有没有泛型 java 泛型编程( 五 )


一个方法是显式的传递一个工厂对象 , 像下面的代码:
interface FactoryT {
public T[] make();
}
public T CollectionT select(FactoryT factory, String statement) {
CollectionT result = new ArrayListT();
/* run sql query using jdbc */
for ( int i=0; i10; i++ ) { /* iterate over jdbc results */
T item = factory.make();
/* use reflection and set all of item’s fields from sql results */
result.add( item );
}
return result;
}
你可以这样调用:
select(new FactoryEmpInfo(){
public EmpInfo make() {
return new EmpInfo();
}
} , ”selection string”);
也可以声明一个类 EmpInfoFactory 来支持接口 Factory:
class EmpInfoFactory implements FactoryEmpInfo { ...
public EmpInfo make() { return new EmpInfo();}
}
然后调用:
select(getMyEmpInfoFactory(), "selection string");
这个解决方案的缺点是它需要下面的二者之一:
调用处那冗长的匿名工厂类,或为每个要使用的类型声明一个工厂类并传递其对象给调用的地方 , 这很不自然 。
使用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;
}
但是这不能给我们返回一个我们要的精确类型的集合 。现在Class是泛型的,我们可以写:
CollectionEmpInfo emps=sqlUtility.select(EmpInfo.class, ”select * from emps”); ...
public static T CollectionT select(ClassTc, String sqlStatement) {
CollectionT result = new ArrayListT();
/* 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;
}
来通过一种类型安全的方式得到我们要的集合 。
这项技术是一个非常有用的技巧,它已成为一个在处理注释(annotations)的新API中被广泛使用的习惯用法 。
7. 新老代码兼容
7.1. 为了保证代码的兼容性 , 下面的代码编译器(javac)允许,类型安全有你自己保证
List l = new ArrayListString();
ListString l = new ArrayList();
7.2. 在将你的类库升级为范型版本时 , 慎用协变式返回值 。
例如 , 将代码
public class Foo {
public Foo create(){
return new Foo();
}
}
public class Bar extends Foo {
public Foo create(){
return new Bar();
}
}
采用协变式返回值风格 , 将Bar修改为
public class Bar extends Foo {
public Bar create(){
return new Bar();
}
}
要小心你类库的客户端 。
JAVA泛型有什么作用?泛型是实泛型还是伪泛型?泛型好处:
泛型简单易用
类型安全 泛型的主要目标是实现java的类型安全 。泛型可以使编译器知道一个对象的限定类型是什么,这样编译器就可以在一个高的程度上验证这个类型
消除了强制类型转换 使得代码可读性好,减少了很多出错的机会
Java语言引入泛型的好处是安全简单 。泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的 , 提高代码的重用率 。
泛型的实现原理
泛型的实现是靠类型擦除技术 类型擦除是在编译期完成的 也就是在编译期 编译器会将泛型的类型参数都擦除成它的限定类型 , 如果没有则擦除为object类型之后在获取的时候再强制类型转换为对应的类型 。在运行期间并没有泛型的任何信息,因此也没有优化 。

推荐阅读