锁定老帖子 主题:项目中List的返回值
精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-01-16
nickevin 写道 Item 43: Return empty arrays or collections, not nulls
public List<Cheese> getCheeseList() { if (cheesesInStock.isEmpty()) return Collections.emptyList(); // Always returns same list else return new ArrayList<Cheese>(cheesesInStock); } from Effective Java : Joshua Bloch 包括楼主以及楼上在内的童鞋们请注意: 1. 对于服务层或者提供服务的类(比如工具类)等,使用默认的empty实现(不仅仅是List,还包括Set, Map等数据结构类)是正确的选择。这样可以避免客户程序调用时对返回值的理解不一致从而出现的NullPointerException。 2. 对于数据实体类,用于ORM映射时(比如domain层),就要小心了,不要随便返回empty实现。尤其是使用了LazyLoading技术来进行一对多mapping时。因为默认的empty实现都是不可写的。这个时候,如果ORM试图延迟装载对应的实体类时(访问主实体时,子实体集合是空的;而第一次访问子实体集合时,ORM会去装载子实体,并填充集合),就会出现异常。 所以大家对于书的理解,对于程序的理解,切记要在一定范围内。 |
|
返回顶楼 | |
发表时间:2010-01-16
0dragon 写道 return null 有造成null pointer exception的可能吧...
所以取之前要判断是否为null 但是逻辑上也还是要判断集合是不是空的啊。 |
|
返回顶楼 | |
发表时间:2010-01-16
凤舞凰扬 写道 nickevin 写道 Item 43: Return empty arrays or collections, not nulls
public List<Cheese> getCheeseList() { if (cheesesInStock.isEmpty()) return Collections.emptyList(); // Always returns same list else return new ArrayList<Cheese>(cheesesInStock); } from Effective Java : Joshua Bloch 包括楼主以及楼上在内的童鞋们请注意: 1. 对于服务层或者提供服务的类(比如工具类)等,使用默认的empty实现(不仅仅是List,还包括Set, Map等数据结构类)是正确的选择。这样可以避免客户程序调用时对返回值的理解不一致从而出现的NullPointerException。 2. 对于数据实体类,用于ORM映射时(比如domain层),就要小心了,不要随便返回empty实现。尤其是使用了LazyLoading技术来进行一对多mapping时。因为默认的empty实现都是不可写的。这个时候,如果ORM试图延迟装载对应的实体类时(访问主实体时,子实体集合是空的;而第一次访问子实体集合时,ORM会去装载子实体,并填充集合),就会出现异常。 所以大家对于书的理解,对于程序的理解,切记要在一定范围内。 非常赞同,开发过程中应该在遵循规范的同时,考虑实际情况作出灵活的变改,规范是死的,程序是活的 |
|
返回顶楼 | |
发表时间:2010-01-17
最后修改:2010-01-17
凤舞凰扬 写道 nickevin 写道 Item 43: Return empty arrays or collections, not nulls
public List<Cheese> getCheeseList() { if (cheesesInStock.isEmpty()) return Collections.emptyList(); // Always returns same list else return new ArrayList<Cheese>(cheesesInStock); } from Effective Java : Joshua Bloch 包括楼主以及楼上在内的童鞋们请注意: 1. 对于服务层或者提供服务的类(比如工具类)等,使用默认的empty实现(不仅仅是List,还包括Set, Map等数据结构类)是正确的选择。这样可以避免客户程序调用时对返回值的理解不一致从而出现的NullPointerException。 2. 对于数据实体类,用于ORM映射时(比如domain层),就要小心了,不要随便返回empty实现。尤其是使用了LazyLoading技术来进行一对多mapping时。因为默认的empty实现都是不可写的。这个时候,如果ORM试图延迟装载对应的实体类时(访问主实体时,子实体集合是空的;而第一次访问子实体集合时,ORM会去装载子实体,并填充集合),就会出现异常。 所以大家对于书的理解,对于程序的理解,切记要在一定范围内。 难怪JPA返回的resultList是不可写的,也无法装载了。 看来楼主要注意了,我想你把所有返回都改写可能会带来风险!! |
|
返回顶楼 | |
发表时间:2010-01-17
引用 1. 对于服务层或者提供服务的类(比如工具类)等,使用默认的empty实现(不仅仅是List,还包括Set, Map等数据结构类)是正确的选择。这样可以避免客户程序调用时对返回值的理解不一致从而出现的NullPointerException。
2. 对于数据实体类,用于ORM映射时(比如domain层),就要小心了,不要随便返回empty实现。尤其是使用了LazyLoading技术来进行一对多mapping时。因为默认的empty实现都是不可写的。这个时候,如果ORM试图延迟装载对应的实体类时(访问主实体时,子实体集合是空的;而第一次访问子实体集合时,ORM会去装载子实体,并填充集合),就会出现异常。 ORM的时候返回不可写的集合,也是问题的根源之一吧。至少这个空的集合还是被分配了内存出来。 如果规范统一起来,都返回null,可能会好点吧? |
|
返回顶楼 | |
发表时间:2010-01-18
BarryWei 写道 引用 1. 对于服务层或者提供服务的类(比如工具类)等,使用默认的empty实现(不仅仅是List,还包括Set, Map等数据结构类)是正确的选择。这样可以避免客户程序调用时对返回值的理解不一致从而出现的NullPointerException。
2. 对于数据实体类,用于ORM映射时(比如domain层),就要小心了,不要随便返回empty实现。尤其是使用了LazyLoading技术来进行一对多mapping时。因为默认的empty实现都是不可写的。这个时候,如果ORM试图延迟装载对应的实体类时(访问主实体时,子实体集合是空的;而第一次访问子实体集合时,ORM会去装载子实体,并填充集合),就会出现异常。 ORM的时候返回不可写的集合,也是问题的根源之一吧。至少这个空的集合还是被分配了内存出来。 如果规范统一起来,都返回null,可能会好点吧? empty实现只占用一份内存,而且基本对象的内存占用我认为是很低的,而且如果没意外很快也就回收了。 |
|
返回顶楼 | |
发表时间:2010-01-18
return new ArrayList(0); 这样就行吧
|
|
返回顶楼 | |
发表时间:2010-01-18
引用 empty实现只占用一份内存,而且基本对象的内存占用我认为是很低的,而且如果没意外很快也就回收了。 这句真没看懂.... |
|
返回顶楼 | |
发表时间:2010-01-18
凤舞凰扬 写道 引用 empty实现只占用一份内存,而且基本对象的内存占用我认为是很低的,而且如果没意外很快也就回收了。 这句真没看懂.... 这个意思大概应该是:返回的那个empty list是一个static的list,在内存中只有一个。 |
|
返回顶楼 | |
发表时间:2010-01-18
我们要把问题分成两个部分:
1. 对于一个类来说,它的方法返回的集合类型是否可写。 2. 对于返回空集合的情况,方法究竟改返回什么Null, EmptyXXX 或者new XXX(0). 对于前者,其实不是讨论的重点,它一般是出现在服务类,并且应该是由服务行为(也就是方法行为)所描述或者确定的。 对于后者,如果已经确认方法应该返回不可写的集合(比如服务类),那么应该返回EmptyXXX,这样一是保证不可写,而是避免客户程序空指针异常。(一个好的业务程序不应该让客户程序有不一致的理解) 而如果是实体类,比如用来进行关系映射的对象,就应该使用new XXX() ,比如new ArrayList()的方式(当然大小可自己限制确定)。 楼上有位童鞋说的 引用 难怪JPA返回的resultList是不可写的,也无法装载了。 其实是指EntityManager(服务类)执行query返回的结果集,而不是对象映射中的子对象集合(子对象集合如果是非可写的,并且子对象被映射成可写映射,就会出异常的)。
|
|
返回顶楼 | |