我怎么...
這頁回答公共的how-to問題抱慌,這些問題可能來自于AutoValue的使用過程中魏宽。你應(yīng)該首先閱讀并理AutoValue介紹 /(簡(jiǎn)單翻譯)
具體builder option的使用單獨(dú)一篇阀圾,在閱讀這篇之前先閱讀 AutoValue with builders /簡(jiǎn)單翻譯。
內(nèi)容
我怎么...
- 為我的value class 生成構(gòu)建者波闹?
- 在內(nèi)部類中使用AutoValue荒吏?
- 使用(不使用)JavaBean樣式的前綴?
- 使用nullable屬性膊毁?
- 屬性驗(yàn)證胀莹?
- 使用復(fù)雜類型的屬性?
- 使用自定義的<code>equals</code>等等媚媒?
- 在<code>equals</code>里面忽略明確的屬性等等嗜逻?
- 含有多個(gè)Create方法,或給它命不同名缭召?
- AutoValue會(huì)實(shí)現(xiàn)那些超類的方法么栈顷?
- 在普通類上使用AutoValue?
- 使我的類實(shí)現(xiàn)Java或者GWT序列化嵌巷?
- 在生成的字段上面添加注解萄凤?
- 讓AutoValue實(shí)現(xiàn)注解類型?
- 包含setter(突變)方法搪哪?
- 生成compareTo靡努?
- 使用原始數(shù)組做為屬性的值?
- 使用Object 數(shù)組做為屬性的值晓折?
- 使一個(gè)@AutoValue類繼承另外一個(gè)惑朦?
- 使訪問器方法private?
- 暴露一個(gè)構(gòu)造器而不是工廠方法作為創(chuàng)建的API漓概?
- 在接口上使用AutoValue而不是抽象類漾月?
為我的value class 生成構(gòu)建者?
--
請(qǐng)查看AutoValue with builders胃珍。 /簡(jiǎn)單翻譯
在內(nèi)部類中使用AutoValue梁肿?
AutoValue 的命名組成:<code>AutoValue_Outer_Middle_Inner</code>,在內(nèi)部類中使用需要按照這種命名方式觅彰,<code>toString</code>方法只會(huì)輸出簡(jiǎn)單類名吩蔑。
class Outer {
static class Middle {
abstract static class Inner {
static Inner create(String foo) {
return new AutoValue_Outer_Middle_Inner(foo);
}
}
}
}
使用(不使用)JavaBean樣式的前綴?
一些開發(fā)者更傾向于在訪問器前面加<code>get-</code>或者<code>is</code>前綴填抬,但是在構(gòu)造器和<code>toString</code>中只使用屬性名烛芬。
AutoValue will do exactly this, but only if you are using these prefixes consistently. In that case, it infers your intended property name by first stripping the get-
or is-
prefix, then adjusting the case of what remains as specified byIntrospector.decapitalize.
AutoValue會(huì)自動(dòng)識(shí)別這些,但是你必選始終如一的使用這些前綴飒责。在這種情況下AutoValue會(huì)剝離你的<code>get-</code>赘娄,<code>is</code>前綴,然后適應(yīng)在Introspector.decapitalize規(guī)定的情況读拆。
注意:為了保持與JavaBean的規(guī)范一致,<code>is</code>前綴只能使用在<code>boolean</code>返回值的方法鸵闪,<code>get</code>前綴可以使用在返回值是任何類型的方法檐晕。
使用nullable屬性?
一般情況下生成的構(gòu)造器將拒絕所有的空值。如果你想接受空值辟灰,只需為訪問方法的參數(shù)中添加一個(gè)<code>@Nullable</code>注解个榕。這樣AutoValue就會(huì)移除空檢測(cè)并為<code>equals</code>,<code>hashCode</code>芥喇,<code>toString</code>方法處理空問題西采。例子:
@AutoValue
public abstract class Foo {
public static Foo create (@Nullable Bar bar) {
return new AutoValue_Foo(bar);
}
@Nullable abstract Bar bar();
}
這個(gè)例子也展示了在<code>create</code>方法中的中對(duì)應(yīng)的參數(shù)添加<code>@Nullable</code>。AutoValue實(shí)際上不需要這個(gè)注解继控,它只用在訪問器上械馆,但是我們還是建議讓它作為調(diào)用者有用的文檔。
屬性驗(yàn)證武通?
空檢查會(huì)被自動(dòng)的添加霹崎,就像下面這樣。對(duì)于其他類型的運(yùn)行前檢查只需要添加在你的工廠方法里面:
static MyType create(String first, String second) {
checkArgument(!first.isEmpty());
return new AutoValue_MyType(first, second.trim());
}
使用復(fù)雜類型的屬性冶忱?
首先尾菇,檢查是否這個(gè)復(fù)雜類型是否有對(duì)應(yīng)的不可變復(fù)雜類型。例如囚枪,<code>List<String></code>和<code>String[]</code>對(duì)應(yīng)Guava不可變類型是<code>ImmutableList<String></code>派诬。如果這樣使用不可變類型作為你的屬性,并且只在構(gòu)造時(shí)接收復(fù)雜類型:
@AutoValue
public abstract class ListExample {
public static ListExample create (String [] mutableNames) {
return new AutoValue_ListExample(ImmutableList.copyOf(mutableNames));
}
public abstract ImmutableList<String> names ();
}
注意:這是一個(gè)非常明智的做法链沼,不是一個(gè)丑陋的實(shí)現(xiàn)方式默赂!
如果沒有合適的不可變類型使用,你需要處理警告忆植。你的靜態(tài)工廠需要給構(gòu)造器傳入一個(gè)參數(shù)的副本放可,你的訪問器應(yīng)該添加一個(gè)明顯的注釋絕對(duì)不要修改這個(gè)返回值。
@AutoValue
public abstract class Mutable Example {
public static MutableExample create(MutablePropertyType ouch) {
// Replace '.clone' below with the right copying code for this type
return new AutoValue_MutableExammple(ouch.clone);
}
/**
* Returns the ouch associated with this object; <b>do not mutate </b> the
* returned object.
* /
public abstract MutablePropertyType outh();
}
注意:這是一個(gè)一個(gè)丑陋的實(shí)現(xiàn)方式朝刊,不是明智的做法耀里!
使用自定義的<code>equals</code>等等?
可以拾氓,AutoValue會(huì)識(shí)別這些并且跳過生成這些方法的代碼冯挎。你寫的代碼邏輯會(huì)遺傳到實(shí)現(xiàn)類,我們稱它為underriding the method咙鞍。
注意一旦你自定義這些方法你就失去了AutoValue的保護(hù)房官。記住下面這些關(guān)于hash code的基本規(guī)則:相同的對(duì)象的必須hash code一致,并且一致的hash code 也暗示相同的對(duì)象续滋。你現(xiàn)在需要使用 guava-testlib的EqualsTester
更透徹理想化的測(cè)試你的類翰守。
最佳實(shí)踐:標(biāo)記你的俯沖方法(underriding methods)為 <code>final</code>類型來讓以后閱讀代碼的人知道這些方法沒有被AutoValue重寫。
注意:如果俯沖方法(underriding methods)定義在抽象類的父類中也是起作用的疲酌,如果你想AutoValue重新覆蓋這個(gè)方法蜡峰,只需要在你的類中重新把這個(gè)方法設(shè)置為抽象就可以了袁。
@AutoValue
class PleaseOverrideExample extends SuperclassThatDefinesToString {
...
// cause AutoValue to generate this even though the superclass has it
@Override public abstract String toString();
}
含有多個(gè)Create方法,或給它命不同名湿颅?
放心大膽的做载绿!AutoValue 不關(guān)心這些。best practice item可能相關(guān)油航。
在<code>equals</code>里面忽略明確的屬性等等崭庸?
假設(shè)你的value class有一個(gè)額外的字段不應(yīng)該包含在<code>equals</code><code>hashCode</code>方法中。一個(gè)通常的原因是因?yàn)檫@個(gè)字段是一個(gè)其他屬性的“緩存”或者派生值谊囚。這種情況下怕享,你直接在你的抽象類里面定義就可以,AutoValue會(huì)直接忽略:
@AutoValue
abstract class DerivedExample {
static DerivedExample create(String realProperty) {
return new AutoValue_DerivedExample(realproperty);
}
abstract String realProperty;
private String derviedProperty;
final String dervedProperty() {
// non-thread- safe Example
if(derivedProperty == null) {
derviedProperty = realProperty().toLowerCase();
}
}
}
另一方面秒啦,如果這個(gè)值是用戶指定熬粗,不是派生的,這種情況稍微更復(fù)雜(但仍舊合理):
@AutoValue
abstract class IgnoreExample {
static IgnoreExample create(String normalProperty, String ignoredProperty) {
IgnoreExample ie = new AutoValue_IgnoreExample(normalProperty);
ie.ignoredProperty = ignoreProperty;
return ie;
}
abstract String normalProperty();
private String ignoredProperty; // sadly, it can't be 'final'
private String ignoredProperty() {
return ignoredProperty;
}
}
這兩種情況的字段都會(huì)在<code>equals</code><code>hashCode</code><code>toString</code>方法中忽略余境,對(duì)AutoValue來說這個(gè)字段根本不存在驻呐。
AutoValue會(huì)實(shí)現(xiàn)那些超類的方法么?
AutoValue會(huì)注意到每個(gè)抽象訪問器芳来,無論他被定義在你的類還是超類中含末。
在普通類上使用AutoValue?
There's nothing to it: just add type parameters to your class and to your call to the generated constructor.
沒有什么不可以:只需要在你的類和生成的構(gòu)造器中上添加類型參數(shù)
使我的類實(shí)現(xiàn)Java或者GWT序列化即舌?
只需要讓你的類添加<code>implements Serializable</code>或者<code>@GwtCompatible(serializable = true)</code>注解(分別)佣盒;這些信息(包括<code>serialVersionUID</code>)都會(huì)復(fù)制到生成類中。
在生成的字段上面添加注解顽聂?
目前還不支持肥惭;然而你抽象訪問器上面的注解同樣會(huì)出現(xiàn)在AutoValue生成的實(shí)現(xiàn)類上。
讓AutoValue實(shí)現(xiàn)注解類型紊搪?
大部分的用戶都應(yīng)該不需要通過編程生成假的注解實(shí)例蜜葱,但是如果你有,使用<code>@AutoValue</code>將導(dǎo)致失敗耀石,因?yàn)?lt;code>Annocation.hashCode</code>的規(guī)范和AutoValue的行為不兼容牵囤。
然而,我們無論如何也會(huì)滿足你滞伟!假如注解是這樣定義的:
public @interface Named {
String value();
}
你需要做的只是這些:
public class Names {
@AutoAnnatation public static Named named(String value) {
return new AutoAnnotaion_Name_named(value);
}
}
查看AutoAnnotation javadoc獲取更多細(xì)節(jié)
包含setter(突變)方法揭鳞?
不可以;AutoValue只生成不可變 value class梆奈;
Note that giving value semantics to a mutable type is widely considered a questionable practice in the first place. Equal instances of a value class are treated as interchangeable, but they can't truly be interchangeable if one might be mutated and the other not.
生成compareTo野崇?
AutoValue 有意不支持這個(gè)特性。使用Java8添加的Comparator
方法或者Guava的ComparisonChain
方法根據(jù)實(shí)際的比較邏輯來實(shí)現(xiàn)會(huì)更好亩钟。
因?yàn)檫@些機(jī)制更易用乓梨,代碼量小钥弯,更靈活,所以AutoValue沒有必要提供督禽。
使用原始數(shù)組做為屬性的值?
請(qǐng)便总处!AutoValue會(huì)生成代碼作用于存儲(chǔ)在數(shù)組中的值狈惫,而不是數(shù)組對(duì)象本身,這正式你所需要的鹦马。注意 mutable properties.給出的警告信息胧谈。
使用Object 數(shù)組做為屬性的值?
這是不允許的荸频,Object數(shù)表現(xiàn)很差不像原始數(shù)組菱肖,它不能被一個(gè)恰當(dāng)?shù)?lt;code>List</code>實(shí)現(xiàn)用較少的代碼替換。
在構(gòu)造期訪問訪問Object數(shù)表是很重要的旭从,參考這里的第一個(gè)例子稳强。
使一個(gè)@AutoValue類繼承另外一個(gè)?
這個(gè)特性是有意不支持的和悦,因?yàn)闆]有正確的實(shí)現(xiàn)方法退疫。參看 Effective Java, 2nd Edition Item 8。
使訪問器方法private鸽素?
sorry褒繁!這是AutoValue幾個(gè)不常見的限制你的API的方式之一。你的訪問器方法可以不是public 的但至少要是包訪問權(quán)限的馍忽。
暴露一個(gè)構(gòu)造器而不是工廠方法作為創(chuàng)建的API棒坏?
sorry!這是AutoValue幾個(gè)不常見的限制你的API的方式之一遭笋。然而Effective Java, Item 1相對(duì)于公共構(gòu)造器更推薦靜態(tài)工廠方法坝冕。
在接口上使用AutoValue而不是抽象類?
接口是不允許的坐梯,我們意識(shí)到接口的唯一好處就是你可以不用寫<code>public abstract</code>徽诲。僅此而已,另一方面你將不能保證不可變性吵血,而且會(huì)導(dǎo)致壞的行為(描述在最佳實(shí)踐)谎替。總的來說蹋辅,我們認(rèn)為這是不值得的钱贯。