gpt4 book ai didi

java - 实现一个 kotlin 泛型函数,从复杂的 java 对象中检索特定字段

转载 作者:行者123 更新时间:2023-12-02 01:59:53 25 4
gpt4 key购买 nike

我正在编写一个 Kotlin 程序,该程序在内部使用 java 库的多个函数(我无法修改)。其中一个函数(我们称之为“feval”)在调用时返回一个具有以下结构的对象:是一个大小为 1 的对象数组,其唯一成员是 com.mathworks.matlab.types 的实例。结构。该结构的每个字段又是一个大小为 1 的数组,其唯一成员是一个变量,类型可以是 int、double、Array 等……这就是我感兴趣的值。

我想用一个类来包装这个困惑,该类提供直接访问“有趣”值的方法。这是我的尝试:

class ExecutionResult (fevalOutput: Array<Any>) {
private val rootObj = fevalOutput[0]
val rootStruct: Struct
init {
if (rootObj is Struct) {
rootStruct = rootObj
}
else {
throw ExecutionResultException("The output doesn't match the expected format")
}
}

fun _get (field: String) : Any {
val container = rootStruct.get(field)
?: throw NoSuchFieldException("The requested field cannot be found in the result")
if (container is Array<*>) {
val value = container[0]
if (value != null) {
return value
}
else {
throw NoSuchFieldException("The requested field cannot be found in the result")
}
}
else{
throw ExecutionResultException("The requested field has an unexpected format")
}
}
inline fun <reified T> get (field: String) : T {
val value = _get(field)
if (value is T) {
return value
}
else {
throw ExecutionResultException(
"The requested field is not a member of the specified class: ${T::class.java}," +
" but a member of: ${value::class.java}")
}
}}

所以现在,从我的代码中我可以做类似的事情:

val output = engine.feval<Array<Any>>(1,functionName, *transmissionParameters.getParameters())
val result = ExecutionResult(output)
val simpleValue = result.get<Double>("simpleValue"))

这基本上就是我想要的。然而这并不总是有效。例如,有时我正在寻找的嵌套值是 double 组的数组。如果我这样做:

val moreComplexValue = result.get<Array<Array<Double>>>("moreComplexValue"))

我生成以下异常:

Exception in thread "main" matlabdriver.ExecutionResultException: The requested field is not a member of the specified class: class [[Ljava.lang.Double;, but a member of: class [[D

如果我理解正确的话,问题是由于我试图将 java native double 组转换为 double 组(类)

有人对如何解决这个问题和/或改进我的包装类有建议吗?

最佳答案

问题在于类型删除不会保留泛型的嵌套类型。在你的情况下,Array<Any>将导致Array::class.javaArray<Array<Double>> 也是如此。 。即使使用具体化类型,函数内部也只有顶级类可用。

Jackson(JSON 序列化)库在反序列化为泛型类型(如 List<MyClass>)时面临同样的问题。 。它们允许您显式指定类型参数:

// represents the generic type Outer<Inner>
val type: JavaType = mapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java)

我建议您提供类似的机制来提供层次结构中的所有类型。也许了解一下 jackson 的JavaType看看机制。使用 Kotlin,您仍然可以使用具体化类型的泛型语法,例如:

val type = dim3<Array, Array, Double>()
// or easier:
val type = array2<Double>()

然后,您可以将该类型(它将泛型类型参数存储为类对象)作为函数的第一个参数传递:

feval(type, otherArgs...)

type本身可以是 data class MatlabType(val subtypes: List<KClass>)具有许多工厂功能,例如 array2() .

关于java - 实现一个 kotlin 泛型函数,从复杂的 java 对象中检索特定字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51764787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com