Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala反射-未调用构造函数_Scala_Reflection - Fatal编程技术网

Scala反射-未调用构造函数

Scala反射-未调用构造函数,scala,reflection,Scala,Reflection,我创建了一个扩展类B的类a,它接受两个参数 当我使用反射创建一个类对象并传递两个参数时,一个对象是create w/o any exception,但两个“constructor”参数不包含我传递的值。 这是故意的行为还是我做错了什么 示例代码: class B (p1: Int = 0, p2: String = "") { ... } class A extends B { ... } val mirror = universe.runtimeMirror(getClass.getCl

我创建了一个扩展类B的类a,它接受两个参数

当我使用反射创建一个类对象并传递两个参数时,一个对象是create w/o any exception,但两个“constructor”参数不包含我传递的值。 这是故意的行为还是我做错了什么

示例代码:

class B (p1: Int = 0, p2: String = "") {
...
}

class A extends B {
...
}


val mirror = universe.runtimeMirror(getClass.getClassLoader)
val classSymbol = mirror.classSymbol(Class.forName("package.A"))
val constructor = mirror.reflectClass(classSymbol).reflectConstructor(
                 classSymbol.toType.decl(universe.termNames.CONSTRUCTOR).asMethod)
val object: B = constructor(1, "C").asInstanceOf[B]
“对象”包含一个实例,但p1=0且p2=”“。我希望它包含p1=1和p2=“C”

如果我将
(p1:Int=0,p2:String=“”)
移动到A,它将按预期工作


是正常行为和我的期望都是错误的,还是我的代码中有错误

我不知道根本原因,但这可能与反射在运行时的工作方式有关

在任何情况下,这类代码都可以满足您的需要(无需重复在超类中指定的默认值)。请注意,您应该从子类中使用的超类中显式指定参数:

class B (p1: Int = 0, p2: String = "") {
  override def toString: String = s"p1 = $p1, p2 = $p2"
}

class A (p1: Int, p2: String) extends B (p1, p2) { }

...

val obj: B = constructor(1, "C").asInstanceOf[B]
println(obj)
输出:

p1 = 1, p2 = C

首先,让我们完全消除图片中的反射,并尝试在不使用反射的情况下执行您正在执行的操作:

class B(p1: Int = 0, p2: String = "")

class A extends B

//val b = (new A(1, "C")).asInstanceOf[B]

// even simpler:
val b = new A(1, "C")
// error: too many arguments for constructor A: ()A
//        new A(1, "C")
//        ^

如您所见,它甚至不编译。为什么?好吧,您定义了一个的构造函数,使其不带任何参数!不知何故,在反射过程中,这些信息会丢失,您最终会通过一个合法调用将参数传递给一个构造函数,而该构造函数不接受任何参数,只会忽略它们。

如果
a扩展了B
,则考虑到您提供的实现,您必须为
B
提供构造函数参数。
A
的构造函数甚至不接受任何参数。如果您尝试在没有反射的情况下执行此操作,则会出现编译错误。不确定为什么会得到默认值而不是运行时错误。