简体   繁体   English

Groovy和Java静态变量行为

[英]Groovy and Java static variable behaviour

I have been doing some Java and Grails3 programming recently. 我最近一直在做一些Java和Grails3编程。 I found some behavior that I don't understand. 我发现了一些我不理解的行为。

There are two groovy classes: 有两个groovy类:

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: 现在,我在Java和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]) 1,2,4,5的结果在两种情况下都相同且易于预测([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] 但是在第3种情况下运行以上代码形式时,Java类输出将是: Sub object, super reference: [Super]并且从Groovy中它将导致: Sub object, super reference: [Sub]

Why is Groovy interpretation of static variable different? 为什么Groovy对static变量的解释不同?

As @dmahapatro states, it's based on Multi Methods , but it's a subtle example. 正如@dmahapatro所述,它基于多方法 ,但它是一个微妙的例子。 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). Java在编译时选择方法签名,因为那时它只有参数变量声明(Object)的类,而不是实例的类(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. Groovy延迟了它的决定,因此它可以确定参数变量引用的实例的类,并使用它来确定哪个方法签名最匹配。

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的继承思想(虚方法)不起作用。 Java again chooses the static from the Class of the reference variable (Super.desc). Java再次从引用变量Class(Super.desc)中选择静态。 Groovy again takes the delayed, instance-based path, and asks the instance what it's static member is (Sub.desc). Groovy再次采用延迟的,基于实例的路径,并询问实例它的静态成员是什么(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. 请注意,大多数人会考虑案例3的错误样式(询问实例类静态成员的值是什么),所以它通常不会出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM