为什么我不能在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 }
}
答案 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语言,都将受到this
或super()
调用中不能使用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