1

I created a class A that extends class B, which takes two parameters.

When I create a class object of A using reflection and passing two parameters, an object is create w/o any exception, but the two "constructor" parameters do not contain the values I passed. Is that the intended behaviour or am I doing something wrong?

Sample code:

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] 

"object" contains an instance of A, but with p1 = 0 and p2 = "". I expected it to contain p1 = 1 and p2 = "C".

If I move (p1: Int = 0, p2: String = "") to A it works as expected.

Is that the normal behaviour and my expectations were just wrong, or is there a mistake in my code?

2
  • If A extends B given the implementation that you provided, you have to provide constructor parameters for B. Commented Sep 5, 2016 at 11:51
  • The constructor for A doesn't even take any arguments. If you tried to do this without reflection, you would get a compile error. Not sure why you get default values instead of a runtime error. Commented Sep 7, 2016 at 16:35

2 Answers 2

1

Let's first take reflection out of the picture completely, and just try to do what you are doing without using reflection:

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") // ^ 

As you can see, it doesn't even compile. Why? Well, you defined A's constructor to take no arguments! Somehow, during the reflection process, this information gets lost and you end with a legal call passing arguments to a constructor that doesn't take any and just ignores them.

Sign up to request clarification or add additional context in comments.

Comments

1

I don't know the underlying reason, but it probably has to do with some quirk in how reflection works at runtime.

In any case this kind of code will get you what you want (without repeating the default values specified in the superclass). Note that you should explicitly specify the parameters from the superclass you are using in the subclass:

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) 

Output:

p1 = 1, p2 = C 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.