не статическая переменная this в статическом методе - PullRequest
5 голосов
/ 07 ноября 2010

Я прочитал эту статью: https://www.ibm.com/developerworks/java/library/j-javadev2-8/index.html

Абстрактный класс Model в листинге 2. имеет static переменное хранилище данных.

abstract class Model {
 static def datastore = DatastoreServiceFactory.datastoreService
  ...

Класс Race in Listing3. расширяет абстрактный класс Model.

class Race extends Model {
 public Race(params){
  super(params)
 }
}

В листинге 5. и листинге 6. используйте статическое хранилище данных для нестатической переменной автора ( this.datastore ).Полагаю, статический метод находится в классе Race.

static def findByName(name){
     def query = new Query(Race.class.simpleName)
     query.addFilter("name", Query.FilterOperator.EQUAL, name)
     def preparedQuery = this.datastore.prepare(query)
     if(preparedQuery.countEntities() > 1){
      return new Race(preparedQuery.asList(withLimit(1))[0])
     }else{
      return new Race(preparedQuery.asSingleEntity())
     }
    }

Как это возможно?Спасибо за объяснение.Том

Ответы [ 2 ]

4 голосов
/ 07 ноября 2010

In - статически скомпилированный - Java, статический код, который вызывает код экземпляра, не будет компилироваться. Это связано с высоким риском того, что статический код не вызывается для экземпляра, а вызывается непосредственно для типа, что может привести к ошибкам во время выполнения.

Хотя теоретически можно статически скомпилировать код Groovy, по умолчанию он компилируется динамически. «Динамически» означает, что отчасти отсутствуют прямые ссылки между артефактами кода (такими как методы, переменные, конструкторы, классы и т. Д.) В байт-коде.

Рассмотрим следующий класс Groovy:

class StaticClass {
    static def someString = "someString"

    static def staticMethod() {
        this.someString
    }

    static def main(args) {
        StaticClass.staticMethod()
        new StaticClass().staticMethod()
    }
}

Используя Groovy-компилятор, groovyc, он компилируется в код, который обеспечивает динамическое выполнение во время выполнения. Следующий код представляет вышеуказанный метод main(..) после компиляции:

public static void main(String[] args) {
    CallSite[] arrayOfCallSite = $getCallSiteArray(); 
    arrayOfCallSite[0].call($get$$class$StaticClass());

    arrayOfCallSite[1].call(arrayOfCallSite[2].callConstructor(
        $get$$class$StaticClass())); return;
}

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

Поскольку в этом простом примере особых случаев нет (метакласс, класс расширения, замыкания, перехватчики и т. Д.), Вполне вероятно, что, в конце концов, вызывается реализация GroovyObject.invokeMethod(String, Object).

Во всей документации Groovy (включая руководство пользователя и вики, но до отсутствуют JavaDocs и отсутствующие исходные файлы в исходном дистрибутиве) механизмы этого "динамического метапрограммирования во время выполнения" скрыты от пользователь - вероятно, из-за его огромной сложности и из-за того, что пользователю не нужно знать об этом подробно. Это довольно интересно для разработчиков ядра Groovy.

В конце концов, трудно сказать , почему this работает, когда не вызывается для экземпляра объекта. Другой вопрос был: должно работать ...

4 голосов
/ 07 ноября 2010

РЕДАКТИРОВАТЬ - вы были правы, я был на неправильном пути раньше.Ответ прост: в groovy вы можете использовать ключевое слово «this» в статических методах.

http://groovy.codehaus.org/Differences+from+Java

При таком использовании «this» относится к классу, а не кпример.Groovy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...