I have been doing some Java and Grails3 programming recently. I found some behavior that I don't understand.
There are two groovy classes:
class Super {
static String desc = "Super"
}
and
class Sub extends Super {
static String desc = "Sub"
}
Now, I'm running following code in Java and Groovy:
Super aSuper = new Super();
Sub sub = new Sub();
Super superSub = new Sub();
System.out.println("Super object: [" + aSuper.getDesc() + "]"); //1
System.out.println("Sub object: [" + sub.getDesc() + "]");//2
System.out.println("Sub object, super reference: [" + superSub.getDesc()+ "]");//3
System.out.println("Super reference: [" + Super.getDesc()+ "]");//4
System.out.println("Sub reference: [" + Sub.getDesc()+ "]");//5
Results of 1,2,4,5 are the same in both cases and easy to predict ([Super], [Sub], [Super], [Sub])
But in case number 3 when running above code form Java class output will be: Sub object, super reference: [Super]
And from Groovy it will result in: Sub object, super reference: [Sub]
Why is Groovy interpretation of static
variable different?
Static variables are generally considered bad because they represent global state and are therefore much more difficult to reason about. In particular, they break the assumptions of object-oriented programming.
Groovy can be used as both programming and scripting Language. Groovy is a superset of Java which means Java program will run in Groovy environment but vice-versa may or may not be possible. Whereas Java is strongly and statically typed programming language.
In Java, static keyword is mainly used for memory management. It can be used with variables, methods, blocks and nested classes. It is a keyword which is used to share the same variable or method of a given class. Basically, static is used for a constant variable or a method that is same for every instance of a class.
Thus static variables can be used to refer to the common property of all objects (which is not unique for each object), for example, college name of students, company name of employees, CEO of a company, etc. It makes the program memory efficient (i.e., it saves memory).
As @dmahapatro states, it's based on Multi Methods, but it's a subtle example. In the documentation, the example is based on method selection given arguments where the variable is of a parent type of the instance held by the argument. Java chooses the method signature at compile time and, since at that time it only has the class of the argument variable declaration (Object), rather than the class of the instance (String). Groovy delays its decision, so it can determine the class of the instance being referred to by the argument variable, and uses that to determine which method signature matches most closely.
In your example above, as you're referring to a static member, which is Class-based, not instance-based, Java's inheritance idea (virtual methods) do not come into play. Java again chooses the static from the Class of the reference variable (Super.desc). Groovy again takes the delayed, instance-based path, and asks the instance what it's static member is (Sub.desc).
Note that most would consider case 3 bad style (asking an instance what the value of a class-static member is), so it shouldn't come up, normally.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With