Java scala反射在这种情况下无法工作
我宣布了一个班级:Java scala反射在这种情况下无法工作,java,scala,reflection,Java,Scala,Reflection,我宣布了一个班级: trait TO { @BeanProperty var id: String = _ @BeanProperty var age : Int = _ @BeanProperty var createdAt : Long = _ @BeanProperty var disable: Boolean = _ } class UMTTestObject extends TO { @BeanProperty var inn
trait TO {
@BeanProperty var id: String = _
@BeanProperty var age : Int = _
@BeanProperty var createdAt : Long = _
@BeanProperty var disable: Boolean = _
}
class UMTTestObject extends TO {
@BeanProperty var inner: UMTInnerTO = _
}
class UMTInnerTO extends TO{}
在反射中,这不适用于UMTInnerObject的设置:
setter.invoke(inner, 0)
setter是UMTInnerObject的设置,而inner是UMTInnerObject的实例
错误消息显示:
java.lang.NoSuchMethodError:me.baihe.blackhole.luna.helpers.TO$class.setAge(Lme/baihe/blackhole/luna/helpers/TO;I)V
这真是个谜--
有人知道为什么吗?此REPL会话演示了如何使用Scala反射API调用setter:
scala> import scala.reflect.runtime. { universe => ru }
import scala.reflect.runtime.{universe=>ru}
scala> trait TO { var age: Int = _ }
defined trait TO
scala> class UMTInnerTO extends TO
defined class UMTInnerTO
scala> val inner = new UMTInnerTO
inner: UMTInnerTO = UMTInnerTO@173379f
scala> val m = ru.runtimeMirror(inner.getClass.getClassLoader)
m: reflect.runtime.universe.Mirror ...
scala> val im = m.reflect(inner)
im: reflect.runtime.universe.InstanceMirror = instance mirror for UMTInnerTO@173379f
scala> val setterSymb = (ru.typeOf[UMTInnerTO].members find (_.name.decoded == "age_=")).get
setterSymb: reflect.runtime.universe.Symbol = method age_=
scala> val setter = im.reflectMethod(setterSymb.asMethod)
setter: reflect.runtime.universe.MethodMirror = method mirror for TO.age_$eq(x$1: scala.Int): scala.Unit (bound to UMTInnerTO@173379f)
scala> inner.age
res0: Int = 0
scala> setter(5)
res1: Any = ()
scala> inner.age
res2: Int = 5
您可以访问以了解代码段中发生了什么
--
更新:不管怎样,如果您仍然对Java API感兴趣,我们开始吧
您应该知道Scala中的setter不使用Java命名约定。您将找不到setAge
方法(至少,如果您不手动声明它的话)。相反,您必须搜索age.=
方法
scala> classOf[UMTInnerTO].getMethod("age_$eq", classOf[Int])
res0: java.lang.reflect.Method = public void UMTInnerTO.age_$eq(int)
scala> inner.age
res1: Int = 0
scala> res0.invoke(inner, 3: Integer)
res2: Object = null
scala> inner.age
res3: Int = 3
这对getter和setter可能很有帮助。您似乎正在处理Java反射API。我鼓励您阅读Scala反射文档,尤其是本文档,以便了解如何使用Scala反射API为
internal
设置值。您能提供更多详细信息吗?例如,您如何获得setter
?@Jesús López González,因此您认为scala不能使用java反射api,因为它具有兼容性?@user1453345 scala也可以使用java反射,但它显然更有限,因为它不支持许多scala概念。我同意这很复杂,但一旦你学会了基本原理,你就会发现这不是火箭科学。顺便说一句,正如@ghik所提到的,如果您能解释setter
的来源,以帮助您使用Java反射API,那就太好了。@Jesús López González,用Java的方式获取setter。classOf[UMTInnerTO].getMethod(“setAge”,classOf[Int])。我调试了它,并在这里设置了断点,它显示setter只是内部的setAge方法,但它无法在内部对象上调用:(谢谢。我以前读过scala反射api:),我认为scala api有点复杂。我只想让setter和getter方法调用普通类,但我为每个字段添加了@BeanProperty。我确实得到了setage的setter,我发现这个问题不是很明显,因为如果我在REPL中执行代码,它就会工作。所以我认为这可能是scala中隐藏的一个bug。对不起,我认为注释是不相关的。绝对正确,设置存在。无论如何,我简化的示例对我来说工作得很好(在REPL和ScalaIDE2.10.1中)。我建议您编辑您的问题,并在“setter是UMTInnerObject的setAge,inner是UMTInnerObject的实例”一句中进一步说明。什么是内部
和UMTInnerObject
?此外,您可以解释它在REPL中工作,并告诉我们您当前的环境。