как вызвать 'final G.Run run = g.new Run ()' в ближайшем будущем - PullRequest
0 голосов
/ 07 сентября 2018

Мне нужна помощь по вызову компилятора scala в ближайшем будущем. Как эта строка будет переводиться в clojure?

final G.Run run = g.new Run();

1 Ответ

0 голосов
/ 07 сентября 2018

Внутренние классы в Java являются просто синтаксическим сахаром для классов, которые передают ссылку на внешний класс в своем (синтаксическом) конструкторе.

Я не знаю ни одного синтаксического сахара для вызова таких конструкторов в Clojure. Но мы можем проверить, как этот синтаксический сахар языка Java преобразуется в сгенерированный байт-код JVM.

Давайте рассмотрим этот пример:

package test;

public class Outer {
    public String oName;

    public Outer(String name) {
        this.oName = name;
    }

    public class Inner {
        public String iName;
        public Inner(String name) {
            this.iName = name;
        }
    }
}

Когда мы скомпилируем этот код и проверим сгенерированный байт-код, мы увидим, что следующий синтаксический конструктор был сгенерирован в классе test.Outer.Inner (команда javap -verbose Outer\$Inner.class):

public test.Outer$Inner(test.Outer, java.lang.String);
    descriptor: (Ltest/Outer;Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=3
         0: aload_0
         1: aload_1
         2: putfield      #1                  // Field this$0:Ltest/Outer;
         5: aload_0
         6: invokespecial #2                  // Method java/lang/Object."<init>":()V
         9: aload_0
        10: aload_2
        11: putfield      #3                  // Field iName:Ljava/lang/String;
        14: return
      LineNumberTable:
        line 12: 0
        line 13: 9
        line 14: 14

В Java мы не используем этот конструктор напрямую, но вызов к нему генерируется компилятором Java.

Итак, этот код в Java:

Outer outer = new Outer("outer");
Outer.Inner inner = outer.new Inner("inner");

компилируется во что-то подобное в байт-коде JVM:

Outer outer = new Outer("outer");
Outer.Inner inner = new Outer.Inner(outer, "inner");

Мы можем перевести это в Clojure и перевести версию байт-кода JVM в код Clojure:

(import '[test Outer Outer$Inner])

(let [outer (Outer. "outer")
      inner (Outer$Inner. outer "inner")]
  (println "Outer" (.-name outer))
  (println "Inner" (.-name inner)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...