Reputation: 60321
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`. How do they differ from each other? Which is is better?
Note: I understand the is done better using reified
e.g. , without need to use Class
at all. But I just want to understand without reified
, what's the different between using Class<*>
vs Class<T>
Upvotes: 2
Views: 162
Reputation: 60321
Both resulted in the exact same decompiled Java code
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
. One example is as below (e.g. 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)
}
}
Upvotes: 0
Reputation: 29914
*
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:
Consider this simple function that takes a List
and prints it:
fun printList(l: List) { println(l) }
It won't compile with the following error:
One type argument expected for interface
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.
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
.
Upvotes: 5