服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > JDK > 查看文档

springside推荐的jdk5.0 feature

原文出自springside wiki,请留意wiki中的更新。

    随着光阴推移,annotation 慢慢在开源框架中推广,泛型渐渐被程序员们用熟,加上autoboxing的小糖,springside终于离不开jdk5.0。

1.autoboxing 与 for each 循环

    本来int的非object性就很无聊,在jdk5.0终于提供了autoboxing功能。这个语法简化糖,被用在了每一个地方。

    for each 循环也改善了原本总要愣一下的collection遍历。不过对于非jdk基本类型,collection必须用泛型声明,如list<book>。

2. 泛型

    泛型大量用于springside core中的基类,使子类更简洁,基类更强大。当然,基类是难读了,所以才需要社区花上这么长的时间来把<t>看到顺眼。

    泛型使用的有两个定式:

2.1 避免强制类型转换

   如果函数输入参数里含class类型,而返回值又是该class的实体,应该将该函数设为泛型函数。最典型的例子是hibernategenericdao的get() 函数

public <t> t get(class<t> entityclass, serializable id) {
   
return (t) gethibernatetemplate().get(entityclass, id);
}

  其中眼花缭乱的第一个<t>声明这是一个泛型函数,第2个t声明返回值为t,第三个class<t>代表 t.class。基类写的辛苦,但子类用得爽快 

   book book = (book)manager.get(book.class,1) 简化成了 book book = manager.get(book.class,1);

2. 2 泛型配合反射api从t获得 t.class。

   最典型的例子hibernateentitydao,子类只需以下定义,即获得要管理的entity的class。

bookmanager extends hibernateentitydao<book>

    此时子类只要声明一次t,上面的book book = (book)manager(book.class,1) 就能简化成book = manager.get(1);

    一举两得地既避免了强制类型转换,又声明了t.class 供框架使用,无须再在manager的构造函数或getentityclass()函数定义entityclass,。

    反射的api 详见genricsutils ,精简的对上面bookmanager的定义反射代码如下:

type gentype = clazz.getgenericsuperclass();
type [] params 
= ((parameterizedtype) gentype).getactualtypearguments();
return (class) params[0];

   泛型反射的关键是获取parameterizedtype,再调用它的getactualtypearguments()方法获得实际绑定的类型。但注意public class bookmanager<book>是不能被反射的,因为擦拭法的缘故。只有在superclass 或者成员变量(field.getgenerictype())等有函数返回parameterizedtype的时候才能成功反射,,

比如 

public class bookmanager extends manager<book>{
}

public class bookaction {
    
private bookmanager<book> manager;
}

 

 

 2.3 其他应用

   1. 在xfire中,list getbooksbycategory()函数返回的结果,需要用aegis.xml 文件声明list中的元素为book.

   而如果定义函数为 list<book> getbooksbycategory(),就不再需要声明,省掉xml配置文件。

3.annotation

     annotation 大幅提升了java的编程模式,springside 目前运用的annotation 有:

     3.1. hibernate annotation

         使用hibernate annotation 代替hbm文件,因为annotation高度的默认性,典型的pojo基本上不需要定义什么,代码的简约性和可管理性大幅提高,直追ror。

         另外,经过测试,annotation 完全能胜任一些比较复杂的mapping定义,如product-book的父子继承关系,order-orderitem-product的经典三角关系。

     2. xfire jsr181 annotation

         jsr181声明的web service,比原本用xml定义的模式节约了xml文件和配置代码的数量。

     3. 声明entity类型的annotation

         使用annotation 声明entity的类型,比如udeletable,auditable 等,比用接口声明的方式有更少的侵入性,详见 侵入,非侵入?interface vs annotation。

4. 三种内置annotation

jdk5.0 有suppresswarnings,deprecated和override 三种内置的annotation:

  @override

   此标签一方面提醒用户这是个重载函数,另一方面保证了父类函数的参数或者名字改变时,子类如果没有跟着变化,就会编译不过。

   虽然有点占地方,但用处的确很大,不会哪天子类被人卖了都不知道。

  所以我设置了让idea6检查所有重载函数必须加上@override标识。

  @suppresswarnings("unchecked")

    此标签可以让编译器忽略某种warning信息,比如减少jdk5.0的集合操作引入范型后无处不在的warning。

    因为有些非jdk5.0的开源库如hibernate, 函数返回的一定是list,而不会是list<user>,这时候ide就会爆出很多warning。用suppresswarning("unchecked")可以让ide安静一些。

  @deprecated

   此标签以前写在javadoc里,现在提到annotation,注释已废弃的函数。用户使用该函数的话,编译时会得到"你用了废柴"的提示。

5.可变参数

用于hibernategenericdao中,简化函数接口。

比如 一个public list find(string hql, object... values),就支持了如下四种调用,避免了以前的煞费苦心的定义多种接口,然后把参数转成统一模式的大量重复定义。