Расширение класса Java во время выполнения не работает
-
19-09-2019 - |
Вопрос
Добрый день, У меня следующая проблема:класс B расширяет класс A, и методы обоих вызываются другим методом в другом классе после создания экземпляра класса B (пример приведен ниже):
public class A{
//fields
//constructors
//methods
}
public class B extends A{
//fields
//constructors
//methods
}
public class CALLER{
public A getA(enum E){
return Factory.getB(otherobject,E);
}
}
public class Factory{
public static B getB(object o,enum e){
//do something with enums and get B
b = new B();
//populate b
return b;
}
}
Класс B не переопределяет ни один метод класса A.Каким-то образом во время компиляции это не приводит к какой-либо ошибке, но во время выполнения ВЫЗЫВАЮЩИЙ класс исключает:java.lang.Ошибка NoSuchMethodError:Factory.getB(объект, перечисление) A
Мой вопрос заключается в следующем:если B расширяет A, то почему метод из другого класса не может вернуть A, даже если его предложение return возвращает объект B напрямую?На самом деле меняется:
public static B getB(object, enum);
с
public static A getB(object, enum);
решает исключение, но затем я получаю другое исключение (classCast), потому что, очевидно, в других частях кода оно ожидает объект типа B, а не A.
Заранее благодарю.
Решение
Вы получили бы это исключение, если бы вы скомпилировали CALLER.java с другой версией Factory.java в которой getB возвращал бы A, затем обновлялся Factory.java чтобы getB возвращал B, затем перекомпилировался Factory.java но не CALLER.java
Обновить:
Возможно, вы хотите сделать что-то подобное:
public abstract class Factory {
public abstract A getInstance(object o, enum e);
}
public class FactoryB extends Factory {
@Override
public B getInstance(object o,enum e){
//do something with enums and get B
b = new B();
//populate b
return b;
}
}
Но тогда необходимо было бы создать экземпляр factory.
Другие советы
Первый из них выглядит как ошибка отражения.Классы отражения Java ищут точную сигнатуру метода "A getB(Object,Enum)", а не "B getB(Object,Enum)".
Во-вторых, до тех пор, пока вы на самом деле создаете объект типа B в своем методе getB(..), он будет возвращать этот объект.Исключение classCast будет выдано только в том случае, если вы создадите новый A вместо нового B.