nerdstone
01/16/2019, 7:59 PMreified
modifier but don't seem to be getting it well could someone please explain it or rather send a link with its usage? That will be helpfulRuckus
01/16/2019, 8:00 PMnfrankel
01/16/2019, 8:01 PMreified
means you’ll be able to get the generic type at runtime
but because the jvm doesn’t allow it
you need inline
as wellnerdstone
01/16/2019, 8:13 PMCasey Brooks
01/16/2019, 8:30 PM<T>
with the known type when it is actually used.
For example:
class JavaClass {
<T> List<T> getList() { ... }
}
// somewhere else
List<String> list = new JavaClass().getList<String>();
effectively compiles in Java to
class JavaClass {
List getList() { ... }
}
// somewhere else
List list = new JavaClass().getList();
The assumption here is that if the type-checker is able to verify at compile-time that everywhere that T is used, it is safe, then at runtime all calls to that method are safe and that T
is not really needed any longer. But there are times that it would be nice to know that T parameter at runtime, which is what reified generics allows for.
An example where you might want to have that T
at runtime is getting a value from a map, where the map can hold any type, and your class needs to check the type of the object in the map.
class JavaClass {
<T> T getItemFromMap(String key) {
T item = _map.get(key); // this is OK
if(item instanceOf T) { // compilation error, T is not known here at runtime
return (T) item
}
else {
return null;
}
}
}
The solution is to pass a Class object matching the T parameter, which has methods to do that check for you:
class JavaClass {
<T> T getItemFromMap(Class<O> itemClass, String key) {
T item = _map.get(key); // this is OK
if(itemClass.isAssignableFrom(item.getClass())) { // this works
return (T) item
}
else {
return null;
}
}
}
But now our method is ugly, and we have to pass 2 parameters to it to get it to work, when at compile-time all the information is readily available. Reified generics make it possible to get around this restriction. The JVM fundamentally does not have the ability to make this work at runtime, so reified generics use a trick at compile-time to make it seem like that: it just inlines the function call and replaced the generic parameter with the actual Class in that inlined code.
Going back to the map example, we can rewrite it using reified generics like this:
fun <reified T> getItemFromMap(String key) {
val item = _map.get(key)
if(T::class.java.isAssignableFrom(item.getClass())) {
return (T) item
}
else {
return null;
}
}
// somewhere else
val list: String = getItemFromMap("key")
effectively compiles to
val item = _map.get(key)
val list: String = if(String::class.java.isAssignableFrom(item.getClass())) {
(String) item
}
else {
null;
}
nerdstone
01/16/2019, 8:51 PM