2015-07-06 3 views
2

Я начинаю с byte-buddy очень впечатляющей библиотекой манипулирования байтовым кодом. Он отлично работает, но у меня есть проблема с подклассов абстрактную, параметризованный класс:Подкласс абстрактный параметризованный класс с byte-buddy

public interface Task<DTO extends IDatabaseObject> { 

    void execute(DTO input); 

    Class<DTO> getDataObjectClass(); 
} 

При этом, как абстрактный класс:

public abstract class AbstractTask<T extends IDatabaseObject> implements Task<T> { 

    protected Class<T> dataObjectClass = /* Call to an external method which retrieves the class from T */; 

    @Override 
    public Class<T> getDataObjectClass() { 
    return dataObjectClass; 
    } 
} 

Я хочу создать конкретный класс, расширяющий

public abstract class AbstractTask<T extends IDatabaseObject> implements Task<T> { 

    protected String SUCCESS_MESSAGE_PREFIX = "task.mess."; 

    protected Class<T> dataObjectClass;// = Introspector.getParameterizedTypeClass(this, AbstractTask.class, 0); 

    @Override 
    public Class<T> getDataObjectClass() { 
    return dataObjectClass; 
    } 

    @Override 
    public String getSuccessMessage(IDatabaseObject t) { 
    final String messageKey = SUCCESS_MESSAGE_PREFIX + this.getClass().getSimpleName(); 
    final MessagesFactory messagesFactory = MessagesFactory.getInstance(); 
    return messagesFactory.isPresent(messageKey) ? messagesFactory.get(messageKey) : ""; 
    } 
} 

Я хочу создать конкретный класс AbstractTask, чтобы заполнить следующее утверждение:

createConcreteImplementation(Person.class).getDataObjectClass() == Person.class 

, где метод createConcreteImplementation создает подкласс через Byte Buddy. Даже если это невозможно, я приветствую предложения по альтернативным путям или приближенно к этому поведению.

ответ

2

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

Однако вы можете всегда переписывает Byte Бадди переопределить метод getDataObjectClass для того, чтобы вернуть класс от метода вместо использования значения поля:

AbstractTask<?> createConcreteImplementation(Class<?> type) 
    return new ByteBuddy() 
    .subclass(AbstractTask.class) 
    .method(named("getDataObjectClass")) 
    .intercept(FixedValue.value(new TypeDescription.ForLoadedType(type))) // (*) 
    .make() 
    .load(type.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) 
    .getLoaded(); 
} 

Явная упаковка на необходимо из-за ошибка, которая исчезнет со следующей версии: https://github.com/raphw/byte-buddy/pull/34#issuecomment-118888979

Смежные вопросы