我想检查对象上是否存在特定名称的成员函数,是否确实调用了该成员函数或对该成员函数进行了引用。
这里我没有对象的类型,即该对象可能未实现任何接口,但具有成员函数cancel()。
我使用了this方法(反射)来检查成员函数是否存在,即if (object::class.members.any { it.name == "cancel" })
,并且当该语句返回true时,我确定该方法确实存在,但是编译器仍不确定' cancel'方法是否存在于对象中
fun canceller(object: Any): KFunction<Any>?
{
var canceller: KFunction<Any>? = null
// check if object has member function 'cancel'
if (object::class.members.any { it.name == "cancel" })
{
// make reference of that member function and return it
canceller = object::cancel //cancel is still not recognized as a member function and gives an error that "Unresolved reference: cancel"
// or just call it now
// object.cancel()
}
return canceller
}
我希望应该将canceller变量分配给value.cancel(),但是即使我们在内部进行了检查,编译器仍不确定对象中是否存在cancel()函数(错误“ Unresolved reference:cancel”) if语句
答案 0 :(得分:0)
我认为您可以为此使用反射。
myObject.javaClass.kotlin.members.any {it.name ==“取消”}
表达“具有所有变量的对象”的想法的更好方法是定义接口并实现所有这些对象
interface Achiever {val name:String}
答案 1 :(得分:0)
这并不是要像这样使用。如果在编译时不知道在运行时要处理什么,则可以使用反射。一些示例:
Class.forName("someTypeString").newInstance()
)中配置的类型现在显示的是函数参考(object::cancel
)。为了使用函数引用,编译器必须知道object
的类型,并且cancel
函数必须针对该类型存在。由于object
的类型为Any
,并且if
条件仅在运行时相关,因此编译器不知道有cancel
函数可用,因此编译失败
请注意,如果您没有做任何特别的事情,您应该检查一个通用的类型/接口。因此,例如,如果您的对象实现接口Cancellable
,则可以将代码更改为以下内容:
fun canceller(object: Any): KFunction<Any>? {
var canceller: KFunction<Any>? = null
// check if object is of type Cancellable
if (object is Cancellable) {
// make reference of the Cancellable::cancel-function
canceller = object::cancel // smart-cast acting
// or you could also call it directly: object.cancel()
}
return canceller
}
或者您可能完全不使用该功能,最终得到的只是:
val someObj : Cancellable = ...
// somewhere later:
someObj.cancel()
反射是相当昂贵的,如果您不能完全确定反射的用途,则不要使用它。
如果您真的知道自己在做什么...那好吧...当然也可以通过反射来调用该函数,如果您通过反射来请求一个函数的存在,那么您也必须通过反射来调用它:
object::class.members.first {
// note: I am using just the first function... if there are several, you need to check which one to use (parameter/type)
it.name == "cancel"
}
.call(object)