Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

no-static variable "this" in static method

Tags:

groovy

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
  ...

The 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

like image 528
Tomáš Avatar asked Nov 07 '10 13:11

Tomáš


People also ask

Can we use non static variable in static method?

In the static method, the method can only access only static data members and static methods of another class or same class but cannot access non-static methods and variables.

Why this is not used in static method?

static method:- there is no need to create an object in order to use static method. means "instance" or object creation doesn't any sense with "static" as per Java rule. So There would be contradiction,if we use both together(static and this) . That is the reason we can not use "this" in static method.

Which type of variables Cannot be used in static method?

Non-static Variable X Cannot be Referenced from a Static Context.


2 Answers

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.

like image 77
hvgotcodes Avatar answered Oct 31 '22 19:10

hvgotcodes


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 ...

like image 29
robbbert Avatar answered Oct 31 '22 19:10

robbbert