2015-04-20 108 views
35

我有一個類如何調用超級構造在龍目島

@Value 
@NonFinal 
public class A { 
    int x; 
    int y; 
} 

我還有一個B類

@Value 
public class B extends A { 
    int z; 
} 

龍目島拋出錯誤說它不能找到A()構造函數,明確叫什麼我想龍目島做的就是給標註b類這樣就產生了下面的代碼:

public class B extends A { 
    int z; 
    public B(int x, int y, int z) { 
     super(x , y); 
     this.z = z; 
    } 
} 

難道我們在龍目島有註解嗎?

回答

51

這在龍目島是不可能的。雖然這將是一個非常好的功能,但它需要解析才能找到超類的構造函數。超級類只有在Lombok被調用的時候才被名字所知。使用導入語句和類路徑來查找實際的類並不是微不足道的。在編譯期間,您不能只使用反射來獲取構造函數列表。

這並非完全不可能,但使用val@ExtensionMethod中的分辨率的結果告訴我們,它很難且容易出錯。

披露:我是一名龍目島開發人員。

+0

@ roel-spilker我們瞭解它背後的複雜性。但是Lombok可以爲構造函數註釋提供一個'inConstructor'方法,我們可以指定Lombok將在生成的構造函數中注入哪個'super'的構造函數? –

+0

afterConstructor會很好,並做一些自動初始化 – Pawel

+0

@ Manu/@ Pawel:請參閱lombok增強請求:https://github.com/peichhorn/lombok-pg/issues/78(當前打開) –

8

Lombok Issue #78引用此頁面https://www.donneo.de/2015/09/16/lomboks-builder-annotation-and-inheritance/與這個可愛的解釋:

@AllArgsConstructor 
public class Parent { 
    private String a; 
} 

public class Child extends Parent { 
    private String b; 

    @Builder 
    public Child(String a, String b){ 
    super(a); 
    this.b = b; 
    } 
} 

因此,您就可以使用生成的建設者是這樣的:

Child.builder().a("testA").b("testB").build(); 

official documentation解釋了這一點,但它沒有明確指出你可以用這種方式來促進它。

我也發現這與Spring Data JPA很好地結合。

+0

你能提供一個與Spring Data JPA一起使用的例子嗎? –

+7

這完全沒有回答這個問題。相反,它是由人工完成的,而問題是如何生成它。同時,拖動@Builder使整個事情變得更加混亂,這與這個問題沒有任何關係。 – Jasper

+0

實際上,這對於那些只想創建繼承結構然後使用構建器的人非常有用。無論如何,這是我使用#lombok的99%的原因。有時候我們只需要手工製作東西就可以按照我們想要的方式工作。所以,謝謝@ jj-zabkar –

3

龍目島不支持這也表明@Value註釋類別final(正如你知道通過使用@NonFinal)也表示。

我發現的唯一解決方法是聲明所有成員最終自己並使用@Data註釋代替。這些子類需要由@EqualsAndHashCode進行註釋,需要一個明確的所有參數的構造爲龍目島不知道如何使用所有ARGS超類之一創建一個:

@Data 
public class A { 
    private final int x; 
    private final int y; 
} 

@Data 
@EqualsAndHashCode(callSuper = true) 
public class B extends A { 
    private final int z; 

    public B(int x, int y, int z) { 
     super(x, y); 
     this.z = z; 
    } 
} 

尤其是子類的構造函數使解決方案有點不整齊,有很多成員的超級班,對不起。

+0

你能解釋一下爲什麼「子類需要用@ EqualsAndHashCode'註釋嗎? 「@ Data」包含了這個註釋嗎? Thx :) –

+0

@GerardB'@ Data'也創建equals()和hashCode(),但不關心任何繼承。爲了確保使用超類equals()和hashCode(),您需要使用callSuper進行顯式生成 –

1

與許多成員超我會建議你使用@Delegate

@Data 
public class A { 
    @Delegate public class AInner{ 
     private final int x; 
     private final int y; 
    } 
} 

@Data 
@EqualsAndHashCode(callSuper = true) 
public class B extends A { 
    private final int z; 

    public B(A.AInner a, int z) { 
     super(a); 
     this.z = z; 
    } 
} 
+0

這是一個有趣的方法,就像它一樣! –

0

如果子類有多個成員,超過母公司,它可以做不是很乾淨,但短期的方式:

@Data 
@RequiredArgsConstructor 
@EqualsAndHashCode(callSuper = true) 
@ToString(callSuper = true) 
public class User extends BaseEntity { 
    private @NonNull String fullName; 
    private @NonNull String email; 
    ... 

    public User(Integer id, String fullName, String email, ....) { 
     this(fullName, email, ....); 
     this.id = id; 
    } 
} 

@Data 
@AllArgsConstructor 
abstract public class BaseEntity { 
    protected Integer id; 

    public boolean isNew() { 
     return id == null; 
    } 
}