下面的代码段返回类类型Object,因此不需要强制转换。
fun <T: Any> getData(clazz: KClass<T>): T? {
}
// Calling function
val article = getData(Article::class)
article.read == true // Call function is possible without casting
现在,我要返回的是List
和特定的Type
。但是,由于::class
的左侧应该是唯一的类,因此我无法传递类似List<Article>::class
的内容。
如何解决?
方法1。创建一个扩展List<Article>
的类并将该类作为参数传递
class ArticleList: ArrayList<Article>
fun <T: Any> getData(clazz: KClass<T>): T? {
}
// Calling function
val articleList = getData(ArticleList::class)
articleList[0].read == true // Call function is possible without casting
方法2。每次调用时,将getData()
函数的输入参数更改为Type
,并在getData()
函数前面添加paramaterType。
fun <T: Any> getData(type: Type): T? {
}
// Calling function
val listType = object : TypeToken<ArrayList<Article>>() {}.type
val data = getData<List<Article>>(listType)
data[0].read == 1 // Call function is possible without casting
当前,我试图避免使用方法1 ,因为我最终将为每个项目创建一个类,而方法2 已经是一种强制转换。>
还有其他解决方案可以以最简单的方式实现吗?
答案 0 :(得分:2)
顺便说一句,您可以使用reified
函数的inline
类型参数不传递KClass
对象:
inline fun <reified T> getData(): T? {
// do something with T::class
}
这不是理想的解决方案,但是您可以创建其他getDataList
函数:
inline fun <reified T> getDataList(): List<T> {
val listType = TypeToken.getParameterized(List::class.java, T::class.java)
// do something
}
答案 1 :(得分:0)
传递实际类型而不是传递类型参数的开销是多少?
由于我也是Kotlin的新手。这就是我想出的。
class Article {
var read = false
}
inline fun <reified T> getData() : T? {
//how do I generically instantiate T, I don't have constructor info here
for(con in T::class.java.constructors) {
if(con.parameterCount == 0) {
return con.newInstance() as T
}
}
return null
}
fun main(){
val article = getData<Article>()
article?.read = true
var articleList = getData<ArrayList<Article>>()
article?.let{
articleList?.add(it)
}
print(articleList)
}