为什么我不能在scala的辅助构造函数中使用this.getClass?

时间:2013-10-01 19:00:51

标签: scala constructor

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

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

一个简单的人为例子(不编译),它显示了我想要做的事情:

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 }
}

2 个答案:

答案 0 :(得分: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之前引用this来调用this的任何超级构造函数。无论您使用何种JVM语言,都将受到thissuper()调用中不能使用this()引用的限制,因为这是类在JVM上运行的方式。

但是,您可以通过重构代码来完全避免此问题,以便在<{em} 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])。如果您正在使用继承(我在这里假设是这种情况),那么这不会给你实际的类名,但是如果你在日志中包含堆栈跟踪,那么你应该能够弄明白。

答案 1 :(得分:1)

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

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

new Foo().c  // -> class Foo