实现从复杂java对象检索特定字段的kotlin通用函数

实现从复杂java对象检索特定字段的kotlin通用函数,java,kotlin,type-conversion,wrapper,Java,Kotlin,Type Conversion,Wrapper,我正在编写一个Kotlin程序,它在内部使用java库的几个函数(我无法修改)。 其中一个函数(我们称之为“feval”)在调用时返回一个具有以下结构的对象:是大小为1的对象数组,其唯一成员是com.mathworks.matlab.types.Struct的实例。这个结构的每个字段也是一个大小为1的数组,它的唯一成员是一个变量,类型可以是int、double、Array等等,这就是我感兴趣的值 我想用一个类来包装这个混乱,该类提供了直接访问“有趣”值的方法。这是我的尝试: class Exec

我正在编写一个Kotlin程序,它在内部使用java库的几个函数(我无法修改)。 其中一个函数(我们称之为“feval”)在调用时返回一个具有以下结构的对象:是大小为1的对象数组,其唯一成员是com.mathworks.matlab.types.Struct的实例。这个结构的每个字段也是一个大小为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}")
    }
}}
如果我理解正确的话,这个问题是由于我正在尝试将java原生double数组转换为double数组(类)


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

问题是类型擦除不会保留泛型的嵌套类型。在您的情况下,
Array
将产生
Array::class.java
,而
Array
也会产生。即使使用具体化类型,函数内部也只有顶级类可用

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

// represents the generic type Outer<Inner>
val type: JavaType = mapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java)
然后可以将该类型(将泛型类型参数存储为类对象)作为第一个参数传递给函数:

feval(type, otherArgs...)

type
本身可能是一个
数据类MatlabType(val subtypes:List)
,具有许多工厂函数,如
array2()

问题是类型擦除不能保留泛型的嵌套类型。在您的情况下,
Array
将产生
Array::class.java
,而
Array
也会产生。即使使用具体化类型,函数内部也只有顶级类可用

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

// represents the generic type Outer<Inner>
val type: JavaType = mapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java)
然后可以将该类型(将泛型类型参数存储为类对象)作为第一个参数传递给函数:

feval(type, otherArgs...)
type
本身可以是一个
数据类MatlabType(val子类型:List)
,具有许多工厂函数,如
array2()

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