假設有以下 (jdbc) 存盤庫:
interface Repo : CrudRepository<MyType, Long> {
@Query("select * from blabla")
fun abc(): List<MyType>
}
對于abc()父介面中包含的方法和方法,介面的自動生成的運行時實作Repo知道如何將結果集序列化為MyType受某些限制約束的實體。
Spring 如何在運行時從泛型引數訪問型別資訊?它如何僅根據介面中提供的型別資訊創建正確的運行時型別串列?
我的理解是,我不會從像mapV1()下面這樣的簽名中獲得足夠的資訊來實體化我的結果,因此我需要引入第二個型別的引數,Class<T>如下所示mapV2():
class Mapper {
fun <T> mapV1(source: Any): T {
/*
try to instantiate a result
of type T reflectively
*/
}
fun <T> mapV2(source: Any, klass: Class<T>): T {
/*
try to instantiate a result
of type T reflectively
*/
}
}
Spring 以某種方式避免了這個問題。
uj5u.com熱心網友回復:
并非所有型別資訊都被洗掉。方法的回傳型別和引數型別、超類和超介面、欄位型別等都作為元資料存盤在類檔案中。Java 反射 API 允許您獲取它們:
// note that the "as ParameterizedType" cast only succeeds if the type is generic
println((Repo::class.java.genericInterfaces[0] as ParameterizedType)
.actualTypeArguments.toList()) // [class MyType, class java.lang.Long]
println((Repo::class.java.getDeclaredMethod("abc").genericReturnType as ParameterizedType)
.actualTypeArguments.toList()) // [class MyType]
您也可以使用 Kotlin 反射 API 執行此操作:
println(Repo::class.supertypes[0].arguments) // [MyType, kotlin.Long]
println(Repo::class.declaredMembers.find { it.name == "abc" }?.returnType?.arguments) // [MyType]
mapV1但是,在這種情況下,您可以獲得的唯一元資料只是“ T”,這不是很有用。您無法獲得呼叫者傳遞給它的引數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/324538.html
