2010-09-03 79 views
3

在我的項目,我已經定義了類似如下的註解:
(省略@Retention@Target爲了簡潔)Java註釋重載?

public @interface DecaysTo { 
    String[] value(); 
} 

由於最初寫它,我們的需求已經改變,現在我已經定義了一個枚舉我希望能夠到位的字符串使用方法:

public enum Particle { 
    ELECTRON, 
    ANTIELECTRON, 
    NEUTRINO, 
    ANTINEUTRINO, 
    ... 
} 

爲了避免更新此註釋的每個實例,我希望能夠構建批註與或者 a Stringenum Particle的成員必須更新此註釋的每個實例以指定屬性。但是,由於我們定義了註釋的屬性,而不是構造函數,所以它似乎不可能超載。

// In a perfect world, either of these would work ... 
public @interface DecaysTo { 
    String[] value(); 
    Particle[] value(); 
} 

@DecaysTo({"Electron", ...}) 
@DecaysTo({Particle.ELECTRON, ...}) 

// without having to explicitly specify which attribute to set: 
public @interface DecaysTo { 
    String[] stringVals(); 
    Particle[] enumVals(); 
} 

@DecaysTo(stringVals = {"Electron", ...}) 
@DecaysTo(enumVals = {Particle.ELECTRON, ...}) 

還企圖:

public @interface DecaysTo { 
    Object[] value(); 
} 

可以做到這一點並不需要通過回去和編輯的代碼的大量任何方式?

回答

4

最好的方法是找到並替換所有以前的註釋。你不想讓舊設計徘徊。在整個重構過程中保持一個乾淨的代碼庫。

假設你不想這樣做,或者你沒有擁有使用註釋的代碼,你應該保留兩種註解類型。在您的註釋處理代碼中,您會查找兩者,如果使用舊的,則將其轉換爲新的。

DecaysToV2 anno = getAnnotation(DecaysToV2.class); 
if(anno = null) 
{ 
    DecaysTo anno_old = getAnnotation(DecaysTo.class); 
    if(anno_old!=null) 
     anno = convert (anno_old); 
} 

DecaysToV2就是你可以IMPL接口:

DecaysToV2 convert(DecaysTo old) 
{ 
    DecaysToV2Impl impl = new DecaysToV2Impl(); 
    impl.value = ... 
    return impl; 
} 
static class DecaysToV2Impl implements DecaysToV2 
{ 
    Particle[] value; 
    public Particle[] value(){ return this.value; } 
} 
+0

那個轉換方法是什麼樣的?你的意思是自己製作一個動態代理,還是其他的東西? – Yishai 2010-09-03 14:25:59

2

你可以不贊成使用這個註解,併爲新的代碼引入一個新的(比如說@DecaysToParticle)。

1

也許你真正需要的是

enum Particle { 
    ELECTRON("Electron"), 
    ... 

    private String name; 
    private Particle(String name) { 
     this.name = name; 
    } 
    public String getName() {return name;} 
} 

(你也可以生成字符串函數的名稱,但這apporach更加靈活)。

另外我不明白是什麼大量的代碼必須改變,因爲(我猜)你的建議不會編譯,我希望這不是你的代碼實際上看起來像。