Перегрузка аннотации Java? - PullRequest
3 голосов
/ 03 сентября 2010

В моем проекте я определил аннотацию, аналогичную следующей:
(для краткости * пропущено @Retention, @Target)

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

С момента первоначального написания этого наши потребностиизменился, и теперь я определил перечисление, которое я хочу использовать вместо строки:

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

Чтобы избежать обновления каждого экземпляра этой аннотации, я хотел бы иметь возможность создавать аннотациюс либо a String или членом enum 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();
}

Есть ли любой способ сделать это, не требующий возврата и редактирования огромного количества кода?

Ответы [ 3 ]

4 голосов
/ 03 сентября 2010

Лучший способ - найти и заменить все предыдущие аннотации.Вы не хотите, чтобы старый дизайн задерживался.Сохраняйте чистую базу кода на протяжении всего процесса рефакторинга.

Предположим, что вы не хотите этого делать или вам не принадлежит код, использующий аннотацию, вы должны сохранить два типа аннотации.в коде обработки аннотаций вы ищете оба, и, если используется старый, конвертируйте его в новый.

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

DecaysToV2 - это просто интерфейс, который вы можете использовать:*

2 голосов
/ 03 сентября 2010

Вы можете просто отказаться от этой аннотации и ввести новую (скажем, @DecaysToParticle) для нового кода.

1 голос
/ 03 сентября 2010

Может быть, вам действительно нужно

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

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

(Вы также можете сгенерировать имя с помощью строковых функций, но этот метод более гибкий).

Кроме того, я не понимаю, какое огромное количество кода нужно изменить, поскольку (я полагаю) ваши предложения не будут компилироваться, я надеюсь, что на самом деле ваш код не такой.

...