2016-09-16 4 views
0

В приведенном ниже коде я пытаюсь вызвать метод объекта, который имеет параметр Int (дающий ему значение 3). Это возвращает ошибку, которую Int и 3 являются несовместимыми типами.Scala reflection с параметром Int

//Using scala's Int does not work! 
object MyObject{ 
    def handleInt(id:Int) : Boolean = { 
    true 
    } 
} 

object testApp extends App { 
    val obj = MyObject.getClass 
    val method = obj.getDeclaredMethod("handleInt", classOf[Int]) //Int.getClass shows the same behavior 
    val rsp = method.invoke(obj, 3) 
} 

Error:(106, 41) the result type of an implicit conversion must be more specific than AnyRef

val rsp = method.invoke(obj, 3) 

Error:(106, 41) type mismatch; found : Int(3) required: Object

val rsp = method.invoke(obj, 3) 

Я попытался модифицировать много вещей здесь, единственный способ это может работать, изменив все подписи к в Java Integer. Код будет выглядеть следующим образом:

//This works with Java's Integer 
object MyObject{ 
    def handleInt(id:Integer) : Boolean = { 
    true 
    } 
} 

object testApp extends App { 
    val obj = MyObject.getClass 
    val method = obj.getDeclaredMethod("handleInt", classOf[Integer]) 
    val rsp = method.invoke(obj, 3) 
} 

Мой вопрос (ы):

  1. Может кто-нибудь объяснить, почему это происходит? I думаю scala's Int обертывает примитив java int (вот почему это не считается объектом ), но я не уверен.
  2. Есть ли способ достичь этого, используя Scala's Int?
  3. Допустимо ли смешивать типы scala и java, как это? Это хорошая практика?

ответ

0

Нет, мы не можем использовать типы Scala.

Его ОК для смешивания типов Java и Scala.

В качестве размышлений рассматриваются чтение байт-кода чтения во время выполнения. На уровне байт-кода видны только типы, которые являются видимыми, - типы Java, потому что все типы scala сводятся к типам Java.

1

Первая проблема заключается в том, что вы вызываете метод на неправильном объекте: obj не имеет handleInt способ, MyObject. Второй вид - это кроссовый случай: invoke принимает varargs, а Scala автоматически не конвертирует Int непосредственно в Object, потому что это не то, что вы обычно хотите делать. Вы можете использовать указание типа, чтобы сказать «поставьте это поле Int в Integer», а затем Scala автоматически преобразует его в Object.

Таким образом, комбинируя эти 2 исправления: вам не нужно менять handleInt или val method, просто

val rsp = method.invoke(MyObject, 3: Integer) 

Чтобы ответить на последний вопрос: использование Integer, java.lang.Double и т.д., не должны быть распространены в Scala, но это не особенно проблематично. И отражение - одна из областей, где вам, возможно, придется их использовать.

Смежные вопросы