如何在Java接口默认方法中模拟静态变量?

如何在Java接口默认方法中模拟静态变量?,java,interface,default-method,Java,Interface,Default Method,为了方便地为我的多个项目类启用日志记录,我决定滥用新的default关键字为我的类创建一个简单的方法特征: default void Log(Level lvl, String msg) { Logger log = Logger.getLogger(this.getClass().getName()); //Log something } 我真正不喜欢的是每次都需要获取日志。如果我用C++工作,我会声明: static Logger log = ...; 每隔调用

为了方便地为我的多个项目类启用日志记录,我决定滥用新的
default
关键字为我的类创建一个简单的方法特征:

  default void Log(Level lvl, String msg) {
    Logger log = Logger.getLogger(this.getClass().getName()); 
    //Log something
  }
我真正不喜欢的是每次都需要获取
日志。如果我用C++工作,我会声明:

static Logger log = ...;
每隔调用一次函数,记录器就会在变量中初始化。在普通类中,我使用此模式模拟静态变量:

class A {
    //By default, this is null until needed
    private Obj cached_obj = null;
    public void doSomethingWithObj(Something thing) {
        //Once needed, it only initialises once
        if(cached_obj==null)
            cached_obj = Obj.generateObj();
        cached_obj.doSomething(thing);
    }
}
但这在接口上是不可能的。接口不能有任何属性


那么,还有其他的解决办法吗?或者Java会再次阻碍我的性能吗?

实际上没有办法缓存这一点,因为根据设计,接口没有与之相关的状态

尽管如此,这可能并不像乍一看那样是个大问题

如果您的日志记录足以使其成为一个问题,JVM可能会对其进行足够的优化,使此版本与假设的缓存版本之间的差异可以忽略不计。此外,任何性能瓶颈都更可能发生在记录日志的过程中,而不是检索日志的过程中


我的建议是对你的应用程序进行分析,看看它是否真的有足够的不同之处让你担心。

在需要记录的类中只需要一个静态的final
Logger
字段似乎并不难。如果您担心复制粘贴错误,您甚至可以编写一个helper方法来获取堆栈跟踪,以确定调用的类是什么,这样它就可以将其传递给
getLogger
method@Namshub这真的很昂贵,因为你必须生成一个堆栈跟踪。重复?你能在C++中发布一个完整的例子,这样我就能理解你实际上想要做什么吗?你说我在用C++工作,我会声明,但是之后发布一个不完整的例子。我不明白C++是如何实现你想要的,所以我想让你澄清一下。