#java #reflection
#java #отражение
Вопрос:
У меня есть интерфейс для реализации структуры данных стека:
public interface Stack<T> {
void push(T element);
//other methods
}
И одной или нескольких реализаций, в которых это реализовано.
И я хочу написать тестер для этого, где может быть протестирован любой экземпляр этого класса. Например:
class StackImpl<T> implement Stack<T>{
//...
}
Для теста вызова я хочу написать это:
Tester.<Integer>test(new StackImpl<Integer>());
И в тестере это:
public static <T> void test(Object any) {
if (any instanceof Stack) {
testQueue((Stack<T>) any);
}
}
private static<T> void testStack(Stack<T> stack) {
new TestStack<>(stack).invoke();
}
И тестовый стек:
public class TestStack<T> implements Test {
private Stack<T> stack;
TestStack(Stack<T> stack) {
this.stack = stack;
}
@Override
public void invoke() {
//and here need help!
}
}
И в методе invoke()
я хочу получить исходный универсальный тип, в данном случае Integer.
Как получить необходимое значение для теста реализации?
Комментарии:
1. Это невозможно из-за удаления типа, это было бы возможно, если бы у вас был отдельный класс, такой как
IntegerStack implements Stack<Integer>
Ответ №1:
Общий тип переменной стирается во время выполнения единственный способ, которым вы могли бы это сделать, — это самостоятельно сохранить тип, т. Е. Добавить метод в свой интерфейс стека для получения типа:
public interface Stack<T> {
...
Class<T> getType();
...
}
Затем в вашем impl добавьте тип в качестве аргумента конструктора:
public class StackImpl<T> implements Stack<T> {
private final Class<T> type;
public StackImpl(Class<T> type) {
this.type = type;
}
@Override
public Class<T> getType() {
return type;
}
}
Итак, теперь у вас будет доступ к типу:
public class TestStack<T> implements Test {
private Stack<T> stack;
TestStack(Stack<T> stack) {
this.stack = stack;
}
public void invoke() {
System.out.println(stack.getType());
}
}
И:
Tester.<Integer>test(new StackImpl<Integer>(Integer.class));
Это не идеально, но это единственный подход, который сработает!