public <T extends UpperBoundClass> T getInstance() {
UpperBoundClass instance = classAttribute.newInstance();
return instance;
}
Этот код делает не фактически вернуть <T>
. Он возвращает экземпляр конкретного Class<? extends UpperBoundClass>
, на который ссылается поле classAttribute
. Весь компилятор может проверить, что instance
назначается (может быть отлит) UpperBoundClass
. Однако не существует заявленной взаимосвязи между этим экземпляром и конкретным типом, представленным в методе подписи <T>
.
Конечный результат: вы получите предупреждение. Это может быть Слушайте до тех пор, пока каждое место, которое вы используете CONSTANT_ONE
или CONSTANT_TWO
, уже ожидает того же типа, что и в своих конструкторах, но компилятор не может обеспечить его выполнение или знать.
Если вы изменили метод к следующему, то вы увидите сайты, использование (в коде вызова), которые не являются строго Типобезопасными, поскольку они предполагают определенный подкласс:
public UpperBoundClass getInstance() {
return classAttribute.newInstance();
}
Кроме того, вы может обеспечить некоторую связь между вашим <T>
и хранимой ссылкой класса:
public <T extends UpperBoundClass> T getInstance(Class<T> type) {
UpperBoundClass instance = classAttribute.newInstance();
return type.cast(instance); // verifies type-safety
}
Но мало смыслом делать это, потому что абонент может либо вызвать type.newInstance()
сам или просто new ClassOne()
(в зависимости от варианта использования). Призыв к type.cast(instance)
мог выкинуть ClassCastException
во время выполнения, но компилятор будет счастлив, потому что он считает это вашей проблемой.
Вы боретесь с тем, что enum
представляет единообразного контракт; и хотя вы можете настраивать отдельные константы с полиморфным поведением, вы не можете использовать generics для параметризации базового API enum
с чем-то, что варьируется от экземпляра к экземпляру.
Связанные чтения: Why shouldn't Java enum literals be able to have generic type parameters?
У вас нет перечислений констант там. –
Кроме того, вы имеете в виду 'newInstance'? –
Технически, все, что вам нужно, это полуколония над декларацией поля, но это действительно странно, что вы можете сделать что-то подобное. – Makoto