开发者

no-static variable "this" in static method

I read this article: https://www.ibm.com/developerworks/java/library/j-javadev2-8/index.html

The abstract class Model in Listing 2. have static variable datastore.

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

T开发者_JAVA技巧he class Race in Listing 3. extends the abstract class Model.

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

In Listing 5. and Listing 6.use the author no-static variable datastore (this.datastore) in static method. I suppose, the static method is in class 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())
     }
    }

How is it possible? Thanks for explanation.

Tom


EDIT -- you were right, I was on the complete wrong track before. The answer is simple, in groovy, you can use the 'this' keyword in static methods.

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

When used like that, 'this' refers to the class, not an instance. Groovy.


In - statically compiled - Java, static code that calls instance code would not compile. That's because of the high risk that the static code is not called upon an instance, but is called on the type, directly - which would lead to runtime errors.

While it is, theoretically, possible to compile Groovy code statically, the default is to compile it dynamically. "Dynamically" means that, partly, there are no direct references between code artifacts (like methods, variables, constructors, classes, etc.) in bytecode.

Consider the following Groovy class:

class StaticClass {
    static def someString = "someString"

    static def staticMethod() {
        this.someString
    }

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

Using the Groovy compiler, groovyc, it is compiled to code that enables dynamic execution at runtime. The following code represents the above main(..) method after compilation:

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;
}

What really happens when this code is called, is hard to say as there is a highly complex, and nested, decision flow and workflow involved, at runtime, that depends on several factors.

As in this simple sample there are no special cases involved (metaclass, expandometaclass, closures, interceptors, and others), it's likely that, after all, an implementation of GroovyObject.invokeMethod(String, Object) is called.

Throughout the Groovy documentation (including the User Guide and the Wiki, but up to missing JavaDocs and missing source files in the source distribution), the mechanics of this "dynamic runtime meta programming" are hidden from the user - probably because of it's huge complexity and because it is not considered necessary for the user to know about that in detail. It's rather interesting for the Groovy core developers, themselves.

So, after all, it's hard to say why this works when not called on an object instance. Another question was whether it should work ...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜