scala:如何在自己的构造函数中获取类
我需要访问在它自己的构造函数中构造的对象的类(出于各种我认为与我的问题无关的详细原因) 我想要这样的东西scala:如何在自己的构造函数中获取类,scala,constructor,Scala,Constructor,我需要访问在它自己的构造函数中构造的对象的类(出于各种我认为与我的问题无关的详细原因) 我想要这样的东西 class Foo(val i:Int) class Bar extends Foo(this.getClass.getName.length) val b = new Bar println(b.i) 打印3(“条”。长度)。但事实并非如此。如果上面的代码在其他对象中,“this”指的是该对象。如果上面的代码不在其他对象中(仅在某个包中),编译器会向 error: this can be
class Foo(val i:Int)
class Bar extends Foo(this.getClass.getName.length)
val b = new Bar
println(b.i)
打印3(“条”。长度)。但事实并非如此。如果上面的代码在其他对象中,“this”指的是该对象。如果上面的代码不在其他对象中(仅在某个包中),编译器会向
error: this can be used only in a class, object, or template
class Bar extends Foo(this.getClass.getName)
^
澄清:我不能将Foo更改为在其主体中使用val而不是构造函数,因为Foo的API已经存在并且是固定的(因此,是的,我必须是构造函数参数)。它在构造函数时需要一个整数参数,但该整数只能通过访问该类来计算
(我知道上面的例子仍然愚蠢和堕落。如果人们关心,我可以详细解释为什么我需要在我真正的项目中上课,)
当然,编译器和运行时在构造过程中都知道要构造的对象的类。用什么语法可以得到它?(没有这样的语法吗?如果没有,我想知道为什么。我很惊讶,似乎没有一种简单、标准的方法来实现这一点。)不确定这是否可能以干净的方式实现。如果你喜欢黑客,你可以做
class Bar extends Foo((new Exception).getStackTrace.apply(0).getClassName)
然而,我强烈地反对它 惰性val解决了这个问题:
object Early
{
abstract class Foo { val name: String }
class Bar extends Foo { lazy val name = getClass.getName }
def
main(args: Array[String]): Unit = {
val b = new Bar
println(b.name)
}
}
收益率:
% scala Early
Early$Bar
那么这个呢:
class Foo(otherName: Option[String] = None) {
val name = otherName.getOrElse(this.getClass.getName)
}
class Bar extends Foo()
val b = new Bar
println(b.name)
你必须解释你想做这件事的动机。名称必须是
Foo
的构造函数参数,还是可以是抽象成员?它必须是val
还是def
呢
你可以这样做
class Foo(val name: String)
class Bar extends Foo("") {
override val name = getClass.getName
}
和newbar()
但我怀疑,如果你的真正动机是已知的,那么有更好的方法来做你真正想做的事情。怎么样
类Bar扩展了Foo(classOf[Bar].getName.length)这似乎可以满足您的需求,而无需使用惰性val,也无需更改基类:
scala> class Base(val name: String)
defined class Base
scala> class Derived extends Base(classOf[Derived].getName)
defined class Derived
scala> new Derived name
res0: String = Derived
顺便说一句,名字Early
是我第一次尝试使用“早期定义”结构来解决这个问题时留下的。Randal,谢谢你的回答。不幸的是,这对我来说不起作用,正如我编辑的问题中更好地描述的那样。这是我发布到StackOverflow的第一个问题。能这么快得到答案真是太好了。谢谢大家。然而,我现在明白了,我必须使我的示例更加复杂,以更好地反映我的真实用例。我想现在要做的是编辑我的问题。我现在就这么做。你意识到访问公共val
仍然是通过(常规多态)方法进行的吗?@chrispy:谢谢你的建议,但是Geoff Reedy的回答对原始问题和稍微编辑的问题都起到了作用。他的回答现在被接受了。杰夫,谢谢你。这就成功了。它保留了Foo的原始API,同时允许使用this.getClass初始化val。我想Bar占用的内存量与Foo相同,但我不确定,我不知道如何验证。@mccallum您可以使用javap-p classname
来显示类中的字段。在这种情况下,Foo和Bar中都会有一个值字段,因此有额外的存储空间。如果Foo的构造函数参数是一个对象,那么最好使用null作为参数,以最小化存储需求。