如果该成员函数存在,如何引用或调用该成员函数
How to make a reference of or call a member function if that member function exists
我想检查对象上是否存在具有特定名称的成员函数,它是否确实调用了该成员函数或引用了该成员函数。
这里我没有对象的类型,即对象可能没有实现任何接口,但有一个成员函数 cancel()。
我使用 this 方法(反射)来检查成员函数是否存在,即 if (object::class.members.any { it.name == "cancel" })
并且当此语句 returns 为真时,我确定该方法确实存在但编译器仍然不确定 '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 语句
我认为您可以为此目的使用反射。
myObject.javaClass.kotlin.members.any { it.name == "cancel" }
表达 "object that has all the variables" 思想的更好方法是定义接口并实现所有这些对象
interface Achiever { val name: String }
不应该这样使用。如果您在编译时不知道在运行时要处理什么,则可以使用反射。一些例子:
- 您需要使用在某些属性文件中配置的类型 (
Class.forName("someTypeString").newInstance()
)
- 您已经编写了一个实用程序来提取对象的内容以进行调试
- 您需要访问您并不真正可见的代码(您无法轻松访问但需要访问的私有字段)
- 还有很多...但大部分时间都很特别use-cases
现在您所显示的是函数参考 (object::cancel
)。为了使用函数引用,编译器必须知道 object
的类型并且 cancel
函数必须存在于该类型。由于 object
是 Any
类型并且 if
条件仅在运行时相关,编译器不知道有可用的 cancel
函数,因此编译失败.
请注意,如果您没有做任何特殊的事情,您应该检查一个普通的 type/interface。因此,例如,如果您的对象实现了一个接口 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)
我想检查对象上是否存在具有特定名称的成员函数,它是否确实调用了该成员函数或引用了该成员函数。
这里我没有对象的类型,即对象可能没有实现任何接口,但有一个成员函数 cancel()。
我使用 this 方法(反射)来检查成员函数是否存在,即 if (object::class.members.any { it.name == "cancel" })
并且当此语句 returns 为真时,我确定该方法确实存在但编译器仍然不确定 '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 语句
我认为您可以为此目的使用反射。
myObject.javaClass.kotlin.members.any { it.name == "cancel" }
表达 "object that has all the variables" 思想的更好方法是定义接口并实现所有这些对象
interface Achiever { val name: String }
不应该这样使用。如果您在编译时不知道在运行时要处理什么,则可以使用反射。一些例子:
- 您需要使用在某些属性文件中配置的类型 (
Class.forName("someTypeString").newInstance()
) - 您已经编写了一个实用程序来提取对象的内容以进行调试
- 您需要访问您并不真正可见的代码(您无法轻松访问但需要访问的私有字段)
- 还有很多...但大部分时间都很特别use-cases
现在您所显示的是函数参考 (object::cancel
)。为了使用函数引用,编译器必须知道 object
的类型并且 cancel
函数必须存在于该类型。由于 object
是 Any
类型并且 if
条件仅在运行时相关,编译器不知道有可用的 cancel
函数,因此编译失败.
请注意,如果您没有做任何特殊的事情,您应该检查一个普通的 type/interface。因此,例如,如果您的对象实现了一个接口 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)