This article summarizes some of the limitations and practical experience of generics
Limitations of generics
-
No primitive type can be used as a type parameter
After type erasings, the List contains the Object field, while in the Java type system, Object and basic types are two systems, which need to interact with each other through “automatic packing and unpacking mechanism”.
Public class ListOfInt {public static void main(String[] args) { List<Integer> li = new ArrayList<>(); for (int i = 0; i < 5; I ++) {li.add(I); } for (int I: li) {system.out.println (I); List<int> List = new ArrayList<>(); }}Copy the code
-
Any operation that needs to know the exact type information at run time will not work.
Because Java generics are compile-time generics (there is no concept of generics once you enter runtime), run-time operations such as type conversions and type determinations have no effect.
Public class Erased<T> {public void f(Object[] args) {// (1) There is no instanceof operation on type parameters, If (args instanceof T) {} var = new T(); T[] array = new T[100]; Array2 = (T[])new Object[100]; array2 = (T[])new Object[100]; }}Copy the code
-
Conflict 1: Method names are the same. Parameter lists are two generic methods of the same type. Overloading will result in the same function signature.
package org.java.learn.generics; import java.util.List; public class UserList<W, T> { void f(List<T> v) {} void f(List<W> v) {} } Copy the code
As you can see from the hints in the figure, after generic erasure, the two methods are signed exactly the same, causing conflict;
-
Conflict 2: When using generic interfaces, avoid implementing the same interface repeatedly
interface Payable<T> {} class Employee implements Payable<Employee> {} class Hourly extends Employee implements Payable<Hourly> {} Copy the code
The IDEA editor says as follows — “Payable cannot be inherited by different type parameters, i.e. the same interface cannot be implemented repeatedly”
-
Type parameters cannot be referenced in static fields or methods
Public class Erased<T> {public static void f(Object[] args) {// There is no class Erased in the static domain if (args instanceof T) {} T var = new T(); T[] array = new T[100]; T[] array2 = (T[])new Object[100]; }}Copy the code
This example is basically the same as in question 2, except that the static keyword is added to the method signature, and the cause of the compilation error is: the type variable cannot be referenced in the static field (as shown in the following figure).
Common experience with generics
-
Try to eliminate exceptions, beginners are easy to write code using native types, or the use of generics improper code, now the editor is very advanced, try to eliminate exceptions prompted; For code that developers themselves certify will work without eliminating cuts, use the @SuppressWarnings(“unchecked”) method to screen exceptions.
-
Use generic classes (or interfaces) whenever possible; Use generic methods whenever possible;
-
When defining apis, use generics whenever possible;
public class PlainResult<T> extends BaseResult { private static final long serialVersionUID = -xxxxxx; private T data; public PlainResult() { } public T getData() { return this.data; } public void setData(T data) { this.data = data; }}Copy the code
-
Use generics when writing basic utility classes;
- Example 1: Generic return value objects
Constructor @noargsconstructor Public class DataListPageInfo<T> {int page; int pageSize; int totalCount; List<T> items = new ArrayList<>(); }Copy the code
- Example 2: Cache manipulation utility class, used here
@Component public class RedisTemplateService { private static final Logger LOGGER = LoggerFactory.getLogger(RedisTemplateService.class); @Resource private RedisTemplate redisTemplate; private String getKey(String key, Object... params) { if (params == null || params.length <= 0) { return key; } return String.format(key, params); Public <T> T getFromJsonCache(Class<T> type, String keyPrefix, Object... params) { try { String ret = getString(keyPrefix, params); return JSON.parseObject(ret, type); } catch (Exception e) { LOGGER.error("json parse error, type={},keyPrefix={},params={}", type, keyPrefix, params, e); } return null; }... }Copy the code
The resources
- Ideas for Java Programming
- Java Core Technology
- “Effective Java”