0

I'm trying to use reflection, pretty much in the same way seen in the answer of this question. The thing is that my code looks like this:

class A {
  def query1(arg: Int): String = { Some code }
  def query2(arg: String): String = { Some code }
  def query3(): String = { Some code }
}

object A {
  def apply(query: String, arg: Any): String = {
    val a = new A
    val method = a.getClass.getMethod(query,arg.getClass)
    method.invoke(a,arg)
  }
}

But this cannot be compiled, and I get an error:

type mismatch; found: Any, required: Object

Any ideas how can I make this work?

Community
  • 1
  • 1
shakedzy
  • 2,853
  • 5
  • 32
  • 62

1 Answers1

2
object A {
  def apply(query: String, arg: AnyRef): String = {
    val a = new A
    val method = a.getClass.getMethod(query, arg.getClass)
    method.invoke(a, arg).toString
  }
}

The problem here is that Any can also be of a primitive type, namely Int, Short, Long and so on, which are not objects in Java, so if the invoke method expects Object, you need a compile time guarantee everything you supply to that method will also be an Object

flavian
  • 28,161
  • 11
  • 65
  • 105
  • Won't work. I get `type mismatch: found Int, required: AnyRef` – shakedzy Aug 14 '16 at 13:59
  • @shakedzy Which is exactly what the method is trying to do, prevent you from using `Int` and any other primitives. You have to manually call `Int.box(33)` and similar casts on other primitives to pass them through as arguments. – flavian Aug 14 '16 at 14:05
  • @shakedzy also this looks like a huge code smell, if you're not just researching, it's worth outlining what you are trying to achieve, if this is about having type refined behaviour, then sealed type families and context bounds are what you want. – flavian Aug 14 '16 at 14:10
  • I can't seem to get it.. I run `A("query2",Int.box(33))` and still get an error.. This zone of Any/AnyRef/AnyVal is not something I fully understand in Scala.. – shakedzy Aug 14 '16 at 14:11
  • @shakedzy 1) please paste the errors and 2) read them before you do, return type of `method.invoke` is `Object`, your method returns a `String`. Of course is doesn't compile. – flavian Aug 14 '16 at 14:15
  • OK, got it to work.. Had to change function `query2` to get an `Integer` rather than `Int`. Thanks! – shakedzy Aug 14 '16 at 14:15
  • 1
    http://stackoverflow.com/questions/2335319/what-are-the-relationships-between-any-anyval-anyref-object-and-how-do-they-m – flavian Aug 14 '16 at 14:16