在下面的代码中,我试图调用一个对象的方法,它有一个Int形参(给它一个值3)。这会返回一个错误,Int
和3
是不兼容的类型。
//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)
}
错误:(106,41)隐式转换的结果类型必须是more比AnyRef
具体val rsp = method.invoke(obj, 3)
Error:(106,41) type mismatch;find: 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)
}
我的问题是:
- 有人能解释一下为什么会这样吗?我认为 scala的
- 有一种方法来实现这使用Scala的
Int
类型? 像这样混合scala和java类型是可以接受的吗?这是一个好的实践吗?
Int
封装了java的原始int
(这就是为什么它不被认为是对象),但我不确定。第一个问题是您在错误的对象上调用方法:obj
没有handleInt
方法,MyObject
有。第二种是一种边缘情况:invoke
接受Object...
变量,Scala不会自动将Int
直接转换为Object
,因为这不是你通常想要做的。你可以使用类型归属来表示"box this Int
into an Integer
",然后Scala会自动将其上转换为Object
。
handleInt
或val method
,只需
val rsp = method.invoke(MyObject, 3: Integer)
回答你的最后一个问题:使用Integer
, java.lang.Double
等不应该在Scala代码中常见,但它不是特别有问题。反射就是其中一个需要用到它们的地方
不,我们不能使用Scala类型。
可以混合Java和Scala类型
As反射处理在运行时读取类字节码。在字节码级别,只有Java类型是可见的,因为所有的scala类型都归结为Java类型。