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

为什么可以';我不能在scala的辅助构造函数中使用this.getClass吗?,scala,constructor,Scala,Constructor,为什么我不能在scala的辅助构造函数中使用this.getClass?还有其他选择吗 更具体地说,我试图在辅助构造函数中调用slf4j的LoggerFactory.getLogger。我现在有一个hack,我被迫将一个logger对象传递给构造函数 一个简单的人为示例(未编译)显示了我正在尝试的操作: class A (numbers : Double) { val logger = LoggerFactory.getLogger(this.getClass) def this(

为什么我不能在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 }
}

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

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

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

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

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

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

这实际上是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
。您将有一个限制,即无论使用何种JVM语言,都不能在
super()
this()
调用中使用
this
引用,因为这是类在JVM上工作的方式

但是,通过重新构造代码,将对
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])
。如果您使用的是继承(我假设这里就是这种情况),那么这不会给出实际的类名,但是如果您在日志中包含堆栈跟踪,那么您应该能够找到它。

这实际上是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
。您将有一个限制,即无论使用何种JVM语言,都不能在
super()
this()
调用中使用
this
引用,因为这是类在JVM上工作的方式

但是,通过重新构造代码,将对
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])
。如果您使用的是继承(我假设这里就是这种情况),那么这不会给出实际的类名,但是如果您在日志中包含堆栈跟踪,那么您应该能够找到它。

不适用于子分类,这很可能是本文的目的。不适用于子分类,这很可能是本文的目的。