#java #generics #inheritance
#java #общие #наследование
Вопрос:
У меня здесь проблема, которую все еще не удается решить, дело в том, что у меня есть этот абстрактный класс:
public abstract class AbstractBean<T> {
private Class<T> entityClass;
public AbstractBean(Class<T> entityClass) {
this.entityClass = entityClass;
}
...
}
Теперь у меня есть другой класс, который наследует этот абстрактный:
@Stateless
@LocalBean
public class BasicUserBean<T extends BasicUser> extends AbstractBean<T> {
private Class<T> user;
public BasicUserBean() {
super(user); // Error: cannot reference user before supertype contructor has been called.
}
}
Мой вопрос в том, как я могу заставить это работать?, Я пытаюсь сделать класс BasicUserBean наследуемым, поэтому, если у меня есть класс PersonBean, который наследует BasicUserBean, тогда я мог бы установить в Generic объект Person, который также наследует объект BasicUser. И в конечном итоге это будет:
@Stateless
@LocalBean
public class PersonBean extends BasicUserBean<Person> {
public PersonBean() {
super(Person.class);
}
...
}
Я просто хочу унаследовать базовую функциональность от BasicUserBean для всех потомков, поэтому мне не нужно повторять один и тот же код среди всех потомков. Спасибо!.
Комментарии:
1. Итак, в чем проблема с вашим последним фрагментом кода?
2. Компилятор выдает ошибку: «не удается сослаться на пользователя до вызова конструктора супертипа».
3. Я имею в виду, какие проблемы с
super(Person.class);
сниппетом?4. какой у вас
BasicUser
класс …? любой фрагмент кода? такжеPerson
класс может быть полезен.5. Вы хотите, чтобы подклассы занимали место
Person.class
?
Ответ №1:
Вам нужно добавить конструктор в BasicUserBean
, взяв Class<T>
public BasicUserBean(Class<T> entityClass) {
super(entityClass);
}
Ваш конструктор без аргументов не будет работать, поскольку класс, который вы расширяете, требует T
. Вы не можете иметь a T
в своем конструкторе, не принимая T
в качестве аргумента; во всяком случае, не без приведения.
Комментарии:
1. Тогда
BasicUserBean()
конструктор без аргументов иuser
свойство member также можно безопасно удалить, поскольку в них не будет необходимости.2. Спасибо, Йохан, это решило проблему. Даже подумав, после этого я получил сообщение компилятора, в котором говорилось «Класс EJB должен иметь общедоступный или защищенный конструктор без аргументов», поэтому я просто добавил конструктор «без аргументов» как к абстрактному классу, так и к классу BasicUserBean, и теперь он работает нормально. Еще раз спасибо.
Ответ №2:
Как указано в ошибке, вы не можете передать поле экземпляра в вызов суперконструктора. Обратите внимание, что поле user
всегда null
находится в точке, которую вы вызываете super
, так в чем же будет смысл. Вам нужно будет передать user
в конструктор и передать это в super
или установить user
как константу.
Ответ №3:
Если AbstractUserBean — это ваш собственный класс, и вам разрешено его изменять, вы можете заменить его конструктор из
public AbstractBean(Class<T> entityClass) {
this.entityClass = entityClass;
}
к этому
public AbstractBean() {
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
this.entityClass = (Class<T>) type.getActualTypeArguments()[0];
}
Таким образом, параметризованные конструкторы вообще не требуются.