2010-09-03 82 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更加灵活)。

另外我不明白是什么大量的代码必须改变,因为(我猜)你的建议不会编译,我希望这不是你的代码实际上看起来像。