Class <*>和Class <t>有什么区别

时间:2019-01-27 13:57:04

标签: android kotlin

我有以下两种编写函数的方式

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)
    }
}

还有这个

Class<*>

我不知道将其设置为reified与“ Class”有什么区别。它们之间有何不同?哪个更好?

注意:我知道使用Class例如可以更好地完成,根本不需要使用reified。但是我只想了解没有Class<*>的情况,使用Class<T><style> html { height: 100%; } body { margin: 0; } #content { width: 100%; } .row { clear: both; padding: 0px; margin: 0px; zoom:1; /* For IE 6/7 (trigger hasLayout) */ &:before, &:after { content:""; display:table; clear:both; } } .c1 { display: block; float:left; width: 100%; } .c2 { display: block; float:left; width: 50%; } </style> <div id="content"> <div class="row"> <div class="c1"> <p></p> </div> </div> <div class="row"> <div class="c2"> <p></p> </div> <div class="c2"> <p></p> </div> </div> </div>

有什么区别

2 个答案:

答案 0 :(得分:5)

*被称为star-projection。在必须指定泛型类型但不必关心它是什么(可能是因为不需要它)时,可以使用它。


由于此问题与Class<T>类没有特殊联系,因此让我用一个简单的示例向您展示它的工作原理:

考虑这个简单的函数,它需要一个List并进行打印:

fun printList(l: List) { println(l) }

它不会编译并出现以下错误:

  

接口List<out E>应该有一个类型参数

我可以这样解决:

fun <T> printList(l: List<T>) { println(l) }

但这很乏味,因为我实际上并不关心T,也不需要它。

以下是星星投影:

fun printList(l: List<*>) { println(l) }

这将进行编译,简洁明了。


因此,在您的特定示例中,您应该使用Class<*>,因为您根本不需要T

答案 1 :(得分:0)

两者都导致完全相同的反编译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()));
  }
}

所以它们是相同的。就像@Willi Mentzel所说的一样,仅在需要使用Class<T>时才应使用T。下面是一个示例(例如,返回它的类型),我们可以得到完全相同的类型

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)
    }
}