繁体   English   中英

Class &lt;*&gt;和Class有什么区别<T>

[英]What's the difference between Class<*> and Class<T>

我有两种编写函数的方法,如下所示

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

和这个

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<*>与'Class`有什么区别。 它们之间有何不同? 哪个更好?

注意:我知道使用reified例如,可以更好地完成,而根本不需要使用Class 但我只是想了解没有reified ,什么是使用之间的不同Class<*> VS Class<T>

*称为星型投影 当您必须指定泛型类型但不必关心它是什么(可能是因为不需要它)时,可以使用它。


由于此问题与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

两者都导致完全相同的反编译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所说的那样,仅在需要使用T时才应使用Class<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)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM