1

为什么我不能在 scala 的辅助构造函数中使用 this.getClass?有没有其他选择?

更具体地说,我试图在辅助构造函数中调用 slf4j 的 LoggerFactory.getLogger。我现在有一个技巧,我被迫将一个记录器对象传递给构造函数。

一个简单的人为示例(不编译),它显示了我正在尝试做的事情:

class A (numbers : Double) {
   val logger = LoggerFactory.getLogger(this.getClass)

   def this(numbersAsStr: String) = this (try { s.toDouble) } catch { case _ => LoggerFactory.getLogger(this.getClass).error("Failed to convert");  0 }
}
4

2 回答 2

6

这实际上是 JVM 的限制,而不是 Scala 问题。这是 Java 中的一个类似示例:

public class ThisTest {

  public final String name;

  public ThisTest(String n) {
    name = n;
  }

  public ThisTest() {
    // trying to use `this` in a call to the primary constructor
    this(this.getClass().getName());
  }

}

当你尝试编译它时,你会得到一个错误:

$ javac ThisTest.java
ThisTest.java:10: error: cannot reference this before supertype constructor has been called
    this(this.getClass().getName());
         ^
1 error

问题是您试图在调用任何超级构造函数this之前进行引用。无论您使用哪种 JVM 语言,都将受到限制,即不能在 a或call 中使用引用,因为这是类在 JVM 上的工作方式。thisthisthissuper()this()

但是,您可以通过重构代码以在调用this 之后放置引用来完全避免此问题:this()

class A (numbers: Double) {
   val logger = LoggerFactory.getLogger(this.getClass)

   def this(numbersAsStr: String) = {
     this ( try { numbersAsStr.toDouble } catch { case _ => 0 } )
     LoggerFactory.getLogger(this.getClass).error("Failed to convert");
   }
}

您实际上可能希望访问引发的异常以获取日志信息。在这种情况下,我只会使用LoggerFactory.getLogger(classOf[A]). 如果您使用继承(我假设这里就是这种情况),那不会给您实际的类名,但是如果您在日志中包含堆栈跟踪,那么您应该能够弄清楚。

于 2013-10-01T19:55:32.440 回答
1

不确定我是否理解这个问题。这是一个猜测:

class Foo(val c: Class[_]) {
  def this() = this(classOf[Foo])
}

new Foo().c  // -> class Foo
于 2013-10-01T19:03:38.710 回答