Помните исчерпывающий вопрос на собеседовании по Java

Java задняя часть .NET JVM

предисловие

Вчера я прочитал вопрос об обработке исключений:Мысли, вызванные вопросом о порядке выполнения 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, и программа завершается.

Суммировать

Этот вопрос очень длинный, но он проверяет только два уровня знаний:

  1. Отношение вызова между подклассом и родительским классом:Динамическая отправка Метод setValue(int value) при вызове конструктора A при вызове new B() и когда super.getValue() определяется в соответствии с фактическим типом неявного объекта. Только когда фактический тип не переопределяет метод, он ищется снизу вверх в соответствии с иерархией наследования. Это может относиться к «Глубокому пониманию JVM».в разделе «Отправка».
  2. try-catch-finallyПоследовательность выполнения см.:Мысли, вызванные вопросом о порядке выполнения Java, наконец

Поймите эти два пункта знания. Также нужно иметь ясную голову и делать это пошагово, проблем быть не должно.

  • Автор этой статьи:Чжао Цзюнь
  • Ссылка на эту статью: Оба 6.net/Java-это-о...
  • Уведомление об авторских правах:Все статьи в этом блоге, если не указано иное, используютCC BY-NC-SA 3.0соглашение. Пожалуйста, укажите источник!