Many unbound generic parameters, like those used in a static method, cannot be recovered at runtime (see Other Threads on Erasure). However there is a common strategy employed for accessing the type satisfying a generic parameter on a class at runtime. This allows for generic code that depends on access to type without having to thread type information through every call.
Background
Generic parameterization on a class can be inspected by creating an anonymous inner class. This class will capture the type information. In general this mechanism is referred to as super type tokens, which are detailed in Neal Gafter's blog post.
Implementations
Three common implementations in Java are:
Example usage
public class DatabaseService<ENTITY_TYPE> { private final DatabaseDao databaseDao = new DatabaseDao(); private final Class<ENTITY_TYPE> entityClass = (Class<ENTITY_TYPE>) new TypeToken<ENTITY_TYPE>(getClass()){}.getRawType(); public List<ENTITY_TYPE> fetchAllEntities() { return databaseDao.getAllOfEntityClass(entityClass); } } public class EmployeeService extends DatabaseService<Employee> {} public class Application { public static void main(String[] args) { EmployeeService employeeService = new EmployeeService(); List<Employee> employees = employeeService.fetchAllEntities(); } }
Code that uses generics has many benefits over non-generic code. Below are the main benefits
Stronger type checks at compile time
A Java compiler applies strong type checking to generic code and issues errors if the code violates type safety. Fixing compile-time errors is easier than fixing runtime errors, which can be difficult to find.
Elimination of casts
The following code snippet without generics requires casting:
List list = new ArrayList(); list.add("hello"); String s = (String) list.get(0);
When re-written to use generics, the code does not require casting:
List<String> list = new ArrayList<>(); list.add("hello"); String s = list.get(0); // no cast
Enabling programmers to implement generic algorithms
By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.
Due to type erasure the following will not work
public <T> void genericMethod() { T t = new T(); // Can not instantiate the type T. }
The type T is erased. Since, at runtime, the JVM does not know what T originally was, it does not know which constructor to call.
Workarounds
public <T> void genericMethod(Class<T> cls) { try { T t = cls.newInstance(); } catch (InstantiationException | IllegalAccessException e) { System.err.println("Could not instantiate: " + cls.getName()); } } genericMethod(String.class);
Which throws exceptions, since there is no way to know if the passed class has an accessible default constructor.
public <T> void genericMethod(Supplier<T> cons) { T t = cons.get(); } genericMethod(String::new);
Learn All in Tamil © Designed & Developed By Tutor Joes | Privacy Policy | Terms & Conditions