Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring Types in Groovy

Tags:

types

groovy

When you don't declare a type for a variable in groovy, it is my understanding that the java virtual machine has to use reflection in order to figure out what type the object is before executing any methods and has the potential of throwing a runtime error.

If that is correct, what about when you declare the type? Does the java virtual machine still end up using reflection because the original code was in groovy? Or is my understanding of this whole matter incorrect in the first place?

like image 811
knpwrs Avatar asked Mar 17 '11 11:03

knpwrs


People also ask

How do I declare a variable in Groovy?

Variables in Groovy can be defined in two ways − using the native syntax for the data type or the next is by using the def keyword. For variable definitions it is mandatory to either provide a type name explicitly or to use "def" in replacement. This is required by the Groovy parser.

What are the data types in Groovy?

Groovy data types can be categorized into simple data types and collective data types. Simple data types include strings, regular expressions (regexes), and numbers. Collective data types include lists, maps, and ranges.

How do I know the type of a variable in Groovy?

You can use the getClass() method to determine the class of an object. Also, if you want to check if an object implements an Interface or Class, you can use the instanceof keyword. That's it about checking the datatype of an object in Groovy.

What is data type in Groovy?

Groovy - Data Types. In any programming language, you need to use various variables to store various types of information. Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in memory to store the value associated with the variable.

How to find the type of an object in Groovy?

We can find the type of any object using instanceof, getClass () and .class operators: Moreover, we can also use the Groovy membership operator in: 5. Conclusion

What is the difference between Java and groovy?

The literal values in Groovy are similar to those in Java, but Groovy allows for generic variables that can hold any type and provides no enforcement and it allows you to declare variables with types and then enforce the type. Declaring a varable using def allows for the flexibility most dynamic programming languges provide.

What is the use of instanceof in Groovy?

instanceof is a binary operator that we can use to check if an object is an instance of a given type. It returns true if the object is an instance of that particular type and false otherwise. Also, Groovy 3 adds the new !instanceof operator. It returns true if the object is not an instance of a type and false otherwise.


2 Answers

The best way to investigate this kind of problem is to look at the generated byte-code yourself. If you create two sample classes:

WithType.groovy:

class WithType {
    String name

    String returnName() { getName() }
}

WithoutType.groovy:

class WithoutType {
    def name

    def returnName() { getName() }
}

Compile them with groovyc:

% groovyc WithType.groovy
% groovyc WithoutType.groovy

And then use javap to spit out the human readable bytecode:

% javap -c WithType > WithType.txt
% javap -c WithoutType > WithoutType.txt

You can then diff the 2 files and look for the returnName() method to see how they're handled differently in how they call the generated getName() method for the name field. If you find the returnName() method, you'll see that the WithType version looks like this:

public java.lang.String returnName();
  Code:
   0:   invokestatic    #24; //Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
   3:   astore_1
   4:   aload_1
   5:   ldc #47; //int 0
   7:   aaload
   8:   aload_0
   9:   invokeinterface #53,  2; //InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;)Ljava/lang/Object;
   14:  invokestatic    #56; //Method $get$$class$java$lang$String:()Ljava/lang/Class;
   17:  invokestatic    #38; //Method org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
   20:  checkcast   #58; //class java/lang/String
   23:  areturn
   24:  nop

and the untyped one looks like this:

public java.lang.Object returnName();
  Code:
   0:   invokestatic    #24; //Method $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
   3:   astore_1
   4:   aload_1
   5:   ldc #47; //int 0
   7:   aaload
   8:   aload_0
   9:   invokeinterface #53,  2; //InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;)Ljava/lang/Object;
   14:  areturn
   15:  nop

The untyped one has fewer instructions because it doesn't need to do any type checking or String conversion on what it's returning. The actual method call to getName() is the same in both the typed and untyped versions:

   9:   invokeinterface #53,  2; //InterfaceMethod org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;)Ljava/lang/Object;

You can see that it's calling an interface method on the groovy CallSite method and passing in a GroovyObject. CallSite is an interface that's implemented by a bunch of the groovy metaObject code. So this is the call to the groovy MOP that dynamically invokes the getName() method.

(this is all with groovy 1.7.5)

like image 154
Ted Naleid Avatar answered Oct 07 '22 13:10

Ted Naleid


It doesn't appear as though type declarations have any specific influence on how Groovy invokes the method. Essentially, as noted on the Groovy wiki, instead of simply invoking the method, Groovy will call invokeMethod() on the object's metaclass, which either delegates to a method defined in the metaclass or performs a reflective lookup of the method.

It's worth noting that the metaclass makes use of a MetaMethod, which, in the worst case, uses a cached reflection lookup, i.e., it only needs to make a single reflective lookup.

Edit

Some of this overhead may be avoidable by using groovypp, which adds static typing capabilities to Groovy code.

like image 26
ig0774 Avatar answered Oct 07 '22 13:10

ig0774