LINUX.ORG.RU

порядок обработки операторов new и .

 


0

4
A {}

B {
    public A getA() { return new A(); }
}

C {
    public void processA (A a) {}

    public void wrapProcessA () {
        processA( new B().getA(); );
    }
}

Этот код работает, но у меня возникает вопрос относительно этого выражения: new B().getA();

Согласно порядковой таблице приоритет у new ниже, чем у .

Почему new B() обрабатывается раньше, чем B(). ?

★★★★★

There is no explicit operator precedence table in the Java Language Specification and different tables on the web and in textbooks disagree in some minor ways.

Вот, видимо, такая ситуация, по мнению авторов таблицы, просто " disagree in some minor ways." :-)

scalist
()

Вроде, приоритеты здесь не при чём. В контексте языков они нужны для однозначного разбора грамматики. В данном случае выражение просто не может никак иначе разбираться (что вообще, кажется, не имело бы смысла, даже если метод вернёт Class).

Другими словами new B() является неделимым выражением, это не new и B(). Т.е. B() может относится только к new, результат которого уже относится к ..

Подобное вообще не работает (как и не должно, собственно):

class A {}

class B {
    public Class getA() { return B.class; }
}

public class C {
    public void processA (Class a) {}

    public void wrapProcessA () {
        processA( new (B().getA()) );
    }
}

P.S. Перечитал, не сильно убедительно звучит, но идея вроде правильная, объясняю её я не очень.

xaizek ★★★★★
()
Ответ на: комментарий от bvn13

ну так я и говорю, что не статик. был бы статиком - порядок был бы другой. не?

static тут никак не повлиял бы на precedence, разве что выдаваемая ошибка была бы (по идее) другой - попытка применить new к ссылке на объект

jcd ★★★★★
() автор топика
Ответ на: комментарий от bvn13

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

scalist
()

Поясню свою мысль: точка у нас выступает, как бы в двоякой роли: если мы ссылаемся на класс через fully qualified name (например, java.lang.Object) или ссылаемся на статический класс/метод через вложенный (к примеру OuterClass.StaticNestedClass o = new OuterClass.StaticNestedClass() ), то точка является просто оператором разрешения пространства имён и тогда точка имеет приоритет более высокий, чем new. Если же мы ссылаемся на нестатический член класса, то, само собой, точка имеет более высокий приоритет (ведь нельзя обращаться к объектам, которые еще не созданы. Можно представить, что вместо точки у нас есть два оператора :: и . Тогда спутать эти два лица двуличной точки было бы намного сложнее

new very::deep::nested::package::OuterClass::InnerClass().method()

scalist
()
Ответ на: комментарий от scalist

то, само собой, точка имеет более высокий приоритет (ведь нельзя обращаться к объектам, которые еще не созданы

У тебя тут очепятка.

Kotolegokot
()

Почему new B() обрабатывается раньше, чем B(). ?

А как ты себе представляешь обработку new B().getA() по-другому? new (B().getA()) работать не может, т.к. new требует указания статического типа.

Согласно порядковой таблице приоритет у new ниже, чем у .

это для случаев new A.B (вложенный класс).

Legioner ★★★★★
()

Начни учтть по русской книжке :)

ii8_ ★★★★
()

Никогда не обращал внимание на приоритет операторов в ЯП. В книгах всегда эти скучные таблицы пропускал. Если где-то не уверен — ставлю скобки и в ус не дую.

CARS ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.