В каком порядке Java оценивает это конкретное выражение: System.out.println ("g." + "Big" + 2 * 3); - PullRequest
0 голосов
/ 02 октября 2019

Оценивается ли 2 * 3 первым, потому что * имеет более высокий приоритет или значение "g." + "Big" оценивается как "g. Big" перед вычислением от 2 * 3 до 6, поскольку выражение читается слева направо.

System.out.println("g."+ " big " + 2*3);

Конечный результат - г. большой 6, но меня больше беспокоит порядок, в котором он оценивается.

Это не дубликат, поскольку он не фокусируется на операции + со строками и целыми числами. Вопрос заключается в том, выполняется ли '*' в конце концов, так как он присутствует после '+', что может быть легко выполнено при чтении выражения (слева направо).

Ответы [ 3 ]

2 голосов
/ 02 октября 2019

Немного по-другому, чтобы компилятор не делал слишком много

static String a() { System.out.print("a "); return "0"; }
static String b() { System.out.print("b "); return "1"; }
static int c() { System.out.print("c "); return 2; }
static int d() { System.out.print("d "); return 3; }

public static void main(String... args) {
    System.out.println(a() + b() + c() * d());
}

вывод:

abcd 016

и дизассемблированный код:

public static void main(java.lang.String...);
  Code:
     0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
     3: invokestatic  #10                 // Method a:()Ljava/lang/String;
     6: invokestatic  #11                 // Method b:()Ljava/lang/String;
     9: invokestatic  #12                 // Method c:()I
    12: invokestatic  #13                 // Method d:()I
    15: imul
    16: invokedynamic #14,  0             // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;
    21: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    24: return

, несмотря на то, что операнды вычисляются в порядке слева направо, сначала выполняется умножение, затем конкатенация.


Здесь разобранный код из вопроса:

System.out.println("g."+ " big " + 2*3);
  Code:
     0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
     3: ldc           #16                 // String g. big 6
     5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V

подтверждает ответ другого Дейва и комментарий , компилятор упростил все операции до одной строки "g. big 6"


С переменными типа int(0: a, 1: b, 2: c, 3: d):

System.out.println(a + b + c * d);
  Code:
    12: iload_0
    13: iload_1
    14: iadd
    15: iload_2
    16: iload_3
    17: imul
    18: iadd
    19: invokevirtual #21                 // Method java/io/PrintStream.println:(I)V
1 голос
/ 02 октября 2019

Оценка - очевидно слева направо .

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

Это не зависит от приоритета;приоритет определяет операнды, а не порядок оценки. Таким образом, операндами * являются 2 и 3, а не g.big2 и 3.

0 голосов
/ 02 октября 2019

В Java оператор * имеет более высокий приоритет, чем оператор +. Это приводит к тому, что утверждение будет оцениваться как следующий

первый шаг 2 * 3 = 6

второй шаг "g."+ " big " = "g. big "

третий шаг "g. big " + 6 = "g. big 6"

выПодробнее о заказе java операторов можно прочитать здесь

...