Java与Groovy内部/外部类的差异
爪哇: 运行时的输出:Java与Groovy内部/外部类的差异,java,groovy,groovyshell,Java,Groovy,Groovyshell,爪哇: 运行时的输出: public final class Outer { public static void main(String[] args) { Inner.inner(); } private static final class Inner { private static void inner() { System.out.println("inner"); outer(); }
public final class Outer {
public static void main(String[] args) {
Inner.inner();
}
private static final class Inner {
private static void inner() {
System.out.println("inner");
outer();
}
}
private static void outer() {
System.out.println("outer");
}
}
public final class Outer {
static main(String[] args) {
Inner.inner()
}
static outer() {
println('outer')
}
static final class Inner {
static inner() {
println('inner')
outer()
}
}
}
Groovy:
inner
outer
运行时的输出:
public final class Outer {
public static void main(String[] args) {
Inner.inner();
}
private static final class Inner {
private static void inner() {
System.out.println("inner");
outer();
}
}
private static void outer() {
System.out.println("outer");
}
}
public final class Outer {
static main(String[] args) {
Inner.inner()
}
static outer() {
println('outer')
}
static final class Inner {
static inner() {
println('inner')
outer()
}
}
}
为什么会出现这种差异?使用
Outer.Outer()。在Java中,编译器识别对outer()
的调用是静态的,并实际将其解析为父类。在字节码中,您将找到对正在调用的静态方法的完全限定引用。相反,Groovy在运行时解析调用(除非您使用@CompileStatic
注释),因此Groovy编译器生成的字节码将没有完全限定的引用。因此,在运行时,Groovy不会知道该方法仅在父类中找到,它只会尝试在内部类中解析它,这将失败
微小的差异:Groovy方法返回对象
,而Java方法返回无效
。这不一定有什么大不了的,但是如果Java代码调用Groovy对象并进行更改,就会产生兼容性问题。您可以在脚本顶部添加一个import static Outer.Outer
,以避免键入类名(有点)…至少可以避免在方法内部键入它
为了补充已经提供的解释,如果您在输出阶段检查Groovy控制台中的AST浏览器,您可以看到这两个类都是顶级的,因此如果没有导入,“Inner”无法解析为Outer的方法
$ groovy Outer
inner
Caught: groovy.lang.MissingMethodException: No signature of method: static Outer$Inner.outer() is applicable for argument types: () values: []
Possible solutions: inner(), use([Ljava.lang.Object;), use(java.lang.Class, groovy.lang.Closure), use(java.util.List, groovy.lang.Closure), putAt(java.lang.String, java.lang.Object), grep()
groovy.lang.MissingMethodException: No signature of method: static Outer$Inner.outer() is applicable for argument types: () values: []
Possible solutions: inner(), use([Ljava.lang.Object;), use(java.lang.Class, groovy.lang.Closure), use(java.util.List, groovy.lang.Closure), putAt(java.lang.String, java.lang.Object), grep()
at Outer$Inner.inner(Outer.groovy:13)
at Outer$Inner$inner.call(Unknown Source)
at Outer.main(Outer.groovy:3)
谢谢(