2015-03-19 55 views
4

番石榴对象(不建议使用)或MoreObjects实现使用ToStringHelper类助洗剂图案,所述add()函数是用于两个基本类型和对象实现:番石榴,Objects/MoreObjects重载以避免自动装箱。

public ToStringHelper add(String name, @Nullable Object value) 
public ToStringHelper add(String name, boolean value) 
public ToStringHelper add(String name, char value) 
... (other primitive type) 

类工作正常,即使没有基本类型的过载,因为自动装箱会转换并调用add(String,Object)函数。

所以我的问题是为所有原语使用重载以避免自动装箱的原因?

1.重复自动装箱可能是一个巨大的开销,但对于大多数情况下,这不会发生。有效的Java项目49,更喜欢原始类型对装箱的基元。

2.Efffective的Java,项目41,P193,

一个安全保守的政策绝不是两个超载出口相同数量的参数。

ToStringHelper示例明显违反了此策略。作者继续在类ObjectOutputStream中讨论,不同的基元有它们自己的函数:writeBoolean(boolean),writeInt(int)...我从来没有能够理解使用不同名称的优点来避免这个特定例子的重载,为什么它好?

任何意见将受到欢迎。

+0

我认为在这里违反#2的原因是没有“破损”的情况 - 所有的原始类型的情况下做相同的东西,相应的盒装类型会 - - 它不像它的罚款布尔,但你会得到'char'的异常。对于'String.valueOf'中的所有基本类型都有原始方法重载,它们能够在不创建盒装对象的情况下进行转换,因此避免不必要的对象创建是有意义的(EJ Item 5)。 – 2015-03-19 05:23:31

+0

紧随“安全保守政策”之上的是不太保守的声明,“避免**令人困惑**超载的使用”。然后它会说'确切地说,构成混淆使用超载的因素有一些争议'。我不认为这是令人困惑的 - ToStringHelper的实现像你期望的那样工作,对于你传递的所有内容。 – 2015-03-19 05:27:38

回答

2

我希望能给出这个答案,因为它是对番石榴语言设计师的第二次猜测。他们也许能够给你一个明确的答案,但是这是我猜测:

不久之前有效的Java第二版,第193页的“保守策略”是语句:

避免混淆超载

的虽然它再继续使用说

究竟是什么构成了一个令人困惑的使用的超载是有争议的

我认为这不是一个混淆的重载使用。我要求这个,因为类的逻辑行为是相同的,如果它是为实现简单:

public ToStringHelper add(String name, @Nullable Object value) 
// No primitive overloads. 

不过,也有在其他EJ其中的建议来发挥作用。一个是第20页的第49项,另一个是第5项“避免创建不必要的对象”。

没有必要创建盒装原语,因为有String.valueOf(...)的重载处理每个基本类型,不可避免地比装箱和调用toString()更有效。

请记住,番石榴是为Google写的,然后他们开源。按照Google的工作规模,使用原始类型和创建盒装类型之间的区别,调用toString()并销毁对象将会是可测量的。

添加这些重载将给予胜利,而主叫方无需做任何事情即可获得。另一方面,如果存在不同名称的重载(例如addChar,addBoolean),您实际上必须有意识地选择您要调用的哪一个,并且很可能很多调用会懒惰地选择Object重载,因为嘿,它可以工作。保持相同的名称可以使其透明工作。


番石榴有很多其他的例子可以避免不必要地通过重载创建对象。例如,ImmutableListof静态工厂方法,重载为零,一,二,...,十一个元素,然后其他一切都由可变重载处理。

可以实现简称为ImmutableList.of(T... elements),但这需要每次一个可变数组,必须防守,以保证该列表的不变性内部复制的隐含创建。

因此,这些重载提供了更高效地构建列表的机会。作为班级的用户,您可能永远不会注意到这一点。

+0

add()函数在很大的范围内使用是一个很好的例子,ImmutableList的例子是正确的,我必须检查出来 – 2015-03-19 12:20:20

2

我对对象进行了更改以添加额外的重载。 是的,这是为了避免自动装箱。我们偶尔会发现性能敏感的代码和自动装箱问题(我们经常会遇到另一个关于w.r.t. autoboxing的先决条件,但我们还没有在那里进行修改)。

FWIW,这里是original bug report