Java 这与Groovy中的Static不同

Java 这与Groovy中的Static不同,java,groovy,static,Java,Groovy,Static,在java中: protected static final Logger LOG = LoggerFactory.getLogger(this.getClass()) 不允许,因为这意味着我们正试图从静态上下文访问非静态成员 但是Groovy允许使用相同的代码段。如何解决 它是否会优先考虑静态,从而使代码看起来像: protected static final Logger LOG = LoggerFactory.getLogger(MyClass.class) protected fin

在java中:

protected static final Logger LOG = LoggerFactory.getLogger(this.getClass())
不允许,因为这意味着我们正试图从静态上下文访问非静态成员

但是Groovy允许使用相同的代码段。如何解决

它是否会优先考虑静态,从而使代码看起来像:

protected static final Logger LOG = LoggerFactory.getLogger(MyClass.class)
protected final Logger LOG = LoggerFactory.getLogger(this.getClass())
或者它会优先考虑非静态引用并使代码看起来像:

protected static final Logger LOG = LoggerFactory.getLogger(MyClass.class)
protected final Logger LOG = LoggerFactory.getLogger(this.getClass())

Groovy添加了静态构造函数来满足这个初始化。看看下面的课程:

import org.slf4j.Logger
import org.slf4j.LoggerFactory

class ClassWithLog {

    protected static final Logger LOG = LoggerFactory.getLogger(this.getClass())

    static void main(String[] args) {
        LOG.info("Hello, world!")
    }
}
让我们将其编译到
.class
文件:

groovyc -cp ~/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar ClassWithLog.groovy

现在让我们来看看字节码是什么样子的,使用<代码> JavaP命令:

javap -l -c ClassWithLog
我将跳过所有不相关的内容,直接转到:(完整列表可在此处找到:)

正如您在列出的字节码中所看到的,Groovy添加了一个静态构造函数(我们还没有定义一个),当在静态上下文中使用时,它使用了
invokestatic
来代替
this.getClass()

如果我们从这个示例性Groovy类中删除第6行,然后将其编译为字节码,那么静态构造函数就不存在了


删除静态日志字段后的完整字节码列表:

如果这样做有效,则很奇怪(我现在没有时间调查字节码)。请注意,
@Slf4j
(或
@Log4j
,如果您使用的是传统记录器)AST通常更简单。或者它可以将声明和分配分开。。。