Подтвердить что ты не робот

Порядок выполнения методов, описывающих экземпляр и аргумент в Java?

В заявлении:

fooFunc().barFunc(bazFunc());

barFunc(), очевидно, не может выполняться до тех пор, пока не будут завершены как bazFunc(), так и fooFunc().

Но гарантирован ли порядок выполнения fooFunc() и bazFunc()?

Связанный (но другой!) вопрос: Порядок выполнения гарантийных параметров в Java?

4b9b3361

Ответ 1

Документация для этого 15.12.4. Оценка времени выполнения метода.

В нем говорится: "Во время выполнения вызов метода требует пять шагов: во-первых, можно вычислить целевую ссылку. Во-вторых, вычисляются выражения аргументов. В-третьих, проверяется доступность метода для вызова. В-четвертых, фактический код для выполняемого метода. В-пятых, создается новый кадр активации, при необходимости выполняется синхронизация, и управление передается коду метода.

В этом примере fooFunc() вызывается как часть вычисления целевой ссылки, а bazFunc() - одно из выражений аргументов, поэтому сначала нужно вызвать fooFunc().

Ответ 2

JLS, Java SE 7 Edition имеет следующий пример, который говорит fooFunc() перед bazFunc(), однако я могу только найти пример - я еще не нашел связанный оператор, который указывает его:

Пример 15.12.4.1-2. Порядок оценки во время вызова метода

В качестве части вызова метода экземпляра (§15.12), существует выражение, которое обозначает объект, подлежащий вызову. Это выражение представляется полностью оценивается перед любой частью любого выражения аргумента методу вычисляется вызов. Так, например, в:

class Test2 { 

    public static void main(String[] args) { 
        String s = "one"; 
        if (s.startsWith(s = "two")) 
            System.out.println("oops"); 
    } 
}

сначала выполняется оценка s до ".startsWith", прежде чем выражение аргумента s = "two". Поэтому ссылка на string "one" запоминается как целевая ссылка перед локальным переменная s изменяется для ссылки на строку "two". В результате Метод startsWith вызывается для целевого объекта "one" с аргументом "two", поэтому результат вызова является ложным, так как строка "one"не начинается с "two". Из этого следует, что тестовая программа не напечатать "oops".

Ответ 3

Сначала fooFunc, затем bazFunc и last barFunc

Вот какой код, который его демонстрирует:

public class OrderJava {
  public static void main(String[] args) {
    fooFunc().barFunc(bazFunc());
  }

  public static Bar fooFunc() {
    System.out.println("I am fooFunc!");
    return new Bar();
  }

  public static class Bar {
    public void barFunc(Object o) {
      System.out.println("I am barFunc!");
    }
  }

  public static Object bazFunc() {
    System.out.println("I am bazFunc!");

    return null;
  }
}

Вывод этого кода:

I am fooFunc!
I am bazFunc!
I am barFunc!

Ответ 4

fooFunc() выполнит сначала, затем bazFunc() и, наконец, barFunc()

Мы все можем согласиться с тем, что fooFunc() должен выполняться до того, как barFunc() будет работать.

Учитывая, что bazFunc() вызывается только тогда, когда barFunc() нуждается в его параметрах, разумно, что это произойдет после fooFunc().