[英]What's the difference between Class<*> and Class<T>
I have two way of writing my functions as below 我有两种编写函数的方法,如下所示
private fun createFragment(fragmentClass: Class<*>, fragmentArgs: Bundle?): Fragment {
try {
val fragment = fragmentClass.newInstance() as Fragment
fragment.arguments = fragmentArgs
return fragment
} catch (exception: Exception) {
throw RuntimeException(exception.message)
}
}
And this 和这个
private fun <T>createFragment(fragmentClass: Class<T>, fragmentArgs: Bundle?): Fragment {
try {
val fragment = fragmentClass.newInstance() as Fragment
fragment.arguments = fragmentArgs
return fragment
} catch (exception: Exception) {
throw RuntimeException(exception.message)
}
}
I don't know what's the different of making it Class<*>
vs 'Class`. 我不知道将其设置为
Class<*>
与'Class`有什么区别。 How do they differ from each other? 它们之间有何不同? Which is is better?
哪个更好?
Note: I understand the is done better using reified
eg , without need to use Class
at all. 注意:我知道使用
reified
例如,可以更好地完成,而根本不需要使用Class
。 But I just want to understand without reified
, what's the different between using Class<*>
vs Class<T>
但我只是想了解没有
reified
,什么是使用之间的不同Class<*>
VS Class<T>
*
is called star-projection . *
称为星型投影 。 You use it when you have to specify a generic type but don't care for what it is (maybe because you don't need it). 当您必须指定泛型类型但不必关心它是什么(可能是因为不需要它)时,可以使用它。
Since this question is not in a special way related to the Class<T>
class, let me show you how it works with a simple example: 由于此问题与
Class<T>
类没有特殊关系,因此让我用一个简单的示例向您展示它的工作方式:
Consider this simple function that takes a List
and prints it: 考虑一下这个简单的函数,它接受一个
List
并打印出来:
fun printList(l: List) { println(l) }
It won't compile with the following error: 它不会编译并显示以下错误:
One type argument expected for interface
List<out E>
接口
List<out E>
期望的一种类型参数
I could fix it like this: 我可以这样解决:
fun <T> printList(l: List<T>) { println(l) }
but this is tedious because I actually don't care for T
and I don't need it. 但这很乏味,因为我实际上并不关心
T
,也不需要它。
Here comes the star-projection into play: 这是星星投影的作用:
fun printList(l: List<*>) { println(l) }
This will compile, is short and concise. 这将编译,简短。
So, in your particular example you should use Class<*>
because you simply don't need T
. 因此,在您的特定示例中,应该使用
Class<*>
因为您根本不需要T
Both resulted in the exact same decompiled Java code 两者都导致完全相同的反编译Java代码
private final Fragment createFragment(Class fragmentClass, Bundle fragmentArgs) {
try {
Object var10000 = fragmentClass.newInstance();
if (var10000 == null) {
throw new TypeCastException("null cannot be cast to non-null type android.support.v4.app.Fragment");
} else {
Fragment fragment = (Fragment)var10000;
fragment.setArguments(fragmentArgs);
return fragment;
}
} catch (Exception var4) {
throw (Throwable)(new RuntimeException(var4.getMessage()));
}
}
So they are the same. 所以他们是一样的。 Like what @Willi Mentzel says, we should only use
Class<T>
if we need to use T
. 就像@Willi Mentzel所说的那样,仅在需要使用
T
时才应使用Class<T>
。 One example is as below (eg return the type of it), that we could get the exact same type 下面是一个示例(例如,返回它的类型),我们可以得到完全相同的类型
private fun <T>createFragmentX(fragmentClass: Class<T>, fragmentArgs: Bundle?): T {
try {
val fragment = fragmentClass.newInstance()
(fragment as Fragment).arguments = fragmentArgs
return fragment
} catch (exception: Exception) {
throw RuntimeException(exception.message)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.