предисловие
Вчера я прочитал вопрос об обработке исключений:Мысли, вызванные вопросом о порядке выполнения Java, наконец, сегодня я увидел более глубокий вопрос на Niuke.com, на этот раз добавив точку знаний об отношениях наследования между дочерними и родительскими классами.
оригинальное название
public class Test {
public static void main(String[] args) {
System.out.println(new B().getValue());
}
static class A {
protected int value;
public A(int v) {
setValue(v);
}
public void setValue(int value) {
this.value = value;
}
public int getValue() {
try {
value++;
return value;
} catch (Exception e) {
System.out.println(e.toString());
} finally {
this.setValue(value);
System.out.println(value);
}
return value;
}
}
static class B extends A {
public B() {
super(5);
setValue(getValue() - 3);
}
public void setValue(int value) {
super.setValue(2 * value);
}
}
}
отвечать
Этот вопрос проверяет порядок выполнения кода. Более интуитивный метод — использовать пошаговую отладку. Давайте посмотрим на процесс выполнения:
Сначала начните выполнение из основного метода, новый объект B, нечего сказать.
Далее выполняется конструктор класса B, и проблем нет.
Затем выполняется параметризованная конструкция родительского класса.
здесь, чтобы выполнитьsetValue(v)
метод, то здесьsetValue()
Должен ли метод выполнять класс B или класс A?
На самом деле такой результат для меня несколько неожиданный, как можно выполнить подкласс B?setValue()
метод?
Поскольку здесь выполняется конструктор B, вызывается метод по умолчанию B. Когда B нет, он найдет метод в своем родительском классе A.
Следующий шагsuper.setValue()
, в котором четко указан метод вызова родительского класса, так что проблем быть не должно.
Ну, здесь свойство value класса A установлено на 10.
А затем вернемся к конструктору A .
Возвращаясь к конструктору B, следующим шагом должен быть вызовgetValue
.
Поскольку подкласса нет, родительский класс называетсяgetValue
метод.
Затем значение в A увеличивается на 1, а затемreturn value
, так как следующее такжеfinally
блок операторов, поэтому сначала выполнитеfinally
блок операторов, а затем возврат.
Еще одинsetValue
метод, то здесь вызывается подкласс B или родительский класс A?
Видно, что здесь вызывается конструктор подкласса B, или вывод только что:
Поскольку здесь выполняется конструктор B, вызывается метод по умолчанию B. Когда B нет, он найдет метод в своем родительском классе A.
Следующим должно быть выполненоsuper.setValue()
То есть его родительский класс AsetValue()
метод.
Это установит значение A равным 22.
Затем вернитесь к методу прямо сейчас и подготовьтесь к печати значения value.После печати он вернется к оператору return в попытке.
Хотя значение value здесь равно 22, значение reutrn было определено до выполнения блока finally, то есть равно 11. Подробнее см.Мысли, вызванные вопросом о порядке выполнения Java, наконец.
Возвращаясь к вызову только что, поскольку значение, возвращенное на предыдущем шаге, равно 11, его следует вызвать здесь.setValue(11- 3);
, здесь вызывается метод B.
рядом с выполнениемsuper.setValue()
, то есть родительский классsetValue()
метод.
Это изменит значение класса A с 22 до 16.
Затем выполняется конструктор класса B, возвращающийся к основному методу, готовый к вызовуgetValue()
метод, поскольку класс B его не имеет, он вызовет родительский класс A.
Здесь значение A увеличивается на 1-17, а затем после окончательного возвращаемого результата возврата содержимое в окончательном операторе выполняется.
вот это сноваsetValue
выбор, какой класс выполняется?
Все равно переведен в класс B, т.к. вызывается основной методnew B().xxx
метод, так что здесь он представляет класс B.
Далее укажите здесьsuper.setValue()
, вызовите метод родителя, установите значение родителя * 2 , а затем вернитесь к блоку finally.
Затем вызовите оператор вывода, результат вывода должен быть 34, и он вернется к оператору возврата в попытке после вывода.
Тогда возвращаемое значение здесь должно быть значением, которое только что было определено, то есть 17, а затем вернуться к основному методу.
Возвращаемое значение здесь равно 17, поэтому выводится 17, и программа завершается.
Суммировать
Этот вопрос очень длинный, но он проверяет только два уровня знаний:
- Отношение вызова между подклассом и родительским классом:Динамическая отправка Метод setValue(int value) при вызове конструктора A при вызове new B() и когда super.getValue() определяется в соответствии с фактическим типом неявного объекта. Только когда фактический тип не переопределяет метод, он ищется снизу вверх в соответствии с иерархией наследования. Это может относиться к «Глубокому пониманию JVM».в разделе «Отправка».
-
try-catch-finally
Последовательность выполнения см.:Мысли, вызванные вопросом о порядке выполнения Java, наконец
Поймите эти два пункта знания. Также нужно иметь ясную голову и делать это пошагово, проблем быть не должно.
- Автор этой статьи:Чжао Цзюнь
- Ссылка на эту статью: Оба 6.net/Java-это-о...
- Уведомление об авторских правах:Все статьи в этом блоге, если не указано иное, используютCC BY-NC-SA 3.0соглашение. Пожалуйста, укажите источник!