Some problems in Java generics

problems java generics

We all know Java stay 1.5 Introduced generic mechanism , The essence of generics is parameterized type , That is to say, the type of variable is a parameter , When using it, specify it as a specific type . Generics can be used for classes 、 Interface 、 Method , You can make the code simpler by using generics 、 Security . In this paper, through reference 《Java Programming idea 》 This paper summarizes the problems that should be paid attention to in the process of using generics, and provides some interview questions related to generics for you to learn and use .

Generics related issues

1、 Generic type reference passing problem

stay Java in , Reference passing like this is not allowed :

ArrayList<String> arrayList1=new ArrayList<Object>();// Compile error 
ArrayList<Object> arrayList1=new ArrayList<String>();// Compile error 


Let's look at the first case first , Expand the first case to the following form :

ArrayList<Object> arrayList1=new ArrayList<Object>();
arrayList1.add(new Object());
arrayList1.add(new Object());
ArrayList<String> arrayList2=arrayList1;// Compile error 


actually , In the 4 Line code , There will be compilation errors . that , Let's assume that it compiles correctly . So when we use arrayList2 For reference get() Method values , All of them String Object of type , But it's actually stored by us Object Object of type , such , There will be ClassCastException 了 . So in order to avoid this kind of very easy mistakes ,Java Such reference passing is not allowed .( That's why generics come along , To solve the problem of type conversion , We can't go against its original intention ).

Looking at the second situation , Expand the second case to the following form :

ArrayList<String> arrayList1=new ArrayList<String>();
arrayList1.add(new String());
arrayList1.add(new String());
ArrayList<Object> arrayList2=arrayList1;// Compile error 


you 're right , This situation is much better than the first one , Minimum , We use arrayList2 It doesn't appear when taking values ClassCastException, Because from String Convert to Object. But , What's the point of doing this , The reason for generics , To solve the problem of type conversion . We use generics , In the end , I still have to force myself , Against the original intention of generic design . therefore java It's not allowed . Besides, , If you use it again arrayList2 Inside add() New objects , So when it's time, when it's time , How do I know what I took out String Type of , still Object What about the type? ? therefore , Pay special attention to reference passing in generics .

2、 Generic type variables cannot be basic data types

Like , No, ArrayList<double>, Only ArrayList<Double>. Because when the type is erased ,ArrayList Type variables in the original class of (T) Replace with Object, but Object Type cannot store double value .

3、 Run time type query

ArrayList<String> arrayList=new ArrayList<String>();if( arrayList instanceof ArrayLi


Because after type erasure ,ArrayList<String> Only the original type , Generic information String Does not exist. .

4、 Problems with generics in static methods and static classes

Static methods and static variables in generic classes cannot use generic type parameters declared by generic classes

public class Test2<T{
public static T one; // Compile error 
public static T show(T one)// Compile error 
return null;
} }


Because the instantiation of a generic parameter in a generic class is to define a generic type object ( for example ArrayList<Integer>) It's designated at the time of , Static variables and static methods don't need objects to call . Objects are not created , How to determine what type this generic parameter is , So of course it's wrong .

But pay attention to distinguish between the following situations :

public class Test2<T{
public static <T >show(T one){// That's right 
return null;
} }


Because this is a generic method , Used in generic methods T It's defined in the method itself T, Not in generic classes T.

Interview questions related to generics

1. Java What are generics in ? What are the benefits of using generics ?

Generics are a mechanism for parameterizing types . It can make the code applicable to all types , To write more general code , For example, the collection framework . Generics are a compile time type validation mechanism . It provides type security at compile time , Make sure that in generic types ( It's usually a collection of generics ) Only objects of the correct type can be used on , Avoid the occurrence of ClassCastException.

2、Java How do generics of work ? What is type erasure ?

The normal work of generics depends on the compiler when compiling the source code , Type check first , Then erase the type and insert the relevant instructions of the cast where the type parameter appears .

The compiler erases all type related information at compile time , So there's no type of information at runtime . for example List<String> Use only one... At runtime List By type . Why erase it ? This is to avoid type inflation .

3. What are qualified wildcards and unqualified wildcards in generics ?

Qualifying wildcards limits the type . There are two kinds of qualified wildcards , One is <? extends T> It ensures that the type must be T To set the upper bound of the type , The other is <? super T> It ensures that the type must be T To set the lower bound of a type . Generic types must be initialized with types within the constraints , Otherwise, it will lead to compilation errors . On the other hand <?> Represents an unqualified wildcard , because <?> You can substitute any type for .

4. List<? extends T> and List <? super T> What's the difference between ?

This is related to the last interview question , Sometimes the interviewer will use this question to evaluate your understanding of generics , Instead of asking you what are qualified wildcards and unqualified wildcards . these two items. List All of the statements are examples of qualified wildcards ,List<? extends T> Any inheritance from T The type of List, and List<? super T> Any T Made up of List. for example List<?extends Number> Acceptable List<Integer> or List<Float>. More information can be found in the links that appear in this paragraph .

5. How to write a generic method , Let it accept generic parameters and return generic types ?

It's not difficult to write generic methods , You need to replace the original type with a generic type , For example, use T, E or K,V And other widely recognized type placeholders . For an example of a generic method, see Java Collection class framework . In the simplest case , A generic method might look like this :

public V put(K key, V value) {
return cache.put(key, value);


6. Java How to use generics to write classes with parameters ?

This is an extension of the last interview question . The interviewer may ask you to write a type safe class with generics , Instead of writing a generic method . The key is still to use generic types instead of primitive types , And use JDK Standard placeholders used in .

7. Write a generic program to implement LRU cache ?

For the love Java It's quite an exercise for programmers . Give you a hint ,LinkedHashMap Can be used to achieve fixed size LRU cache , When LRU When the cache is full , It will move the oldest key value pair out of the cache .LinkedHashMap There is one provided called removeEldestEntry() Methods , The method will be put() and putAll() Call to delete the oldest key value pair .

8. You can take List<String> Pass it on to an acceptor List<Object> Parameter method ?( See above )

For anyone who is not familiar with generics , This Java Generic topics seem confusing , Because at first sight String It's a kind of Object, therefore List<String> Should be able to be used in need of List<Object> The place of , But that's not the case . If you do, it will lead to compilation errors . If you think about it further , You'll find that Java It makes sense to do so , because List<Object> Can store any type of object including String, Integer wait , and List<String> But it can only be used to store Strings.

9. Array Can I use generics in ?

This may be Java The simplest of the general interview questions , Of course, if you know Array In fact, generics are not supported , That's why Joshua Bloch stay Effective Java It is recommended to use List Instead of Array, because List It can provide type security guarantee at compile time , and Array But not .

10. How to stop Java Warning of type unchecked in ?

If you mix generics with primitive types , For example, the following code ,Java 5 Of javac The compiler will generate an unchecked type warning , for example List<String> rawList = new ArrayList() Be careful : Use of unchecked or unsafe operations ; This warning can be used @SuppressWarnings("unchecked") Comment to mask .

11、Java in List<Object> And the original type List The difference between ?

Primitive and parameterized types <Object> The main difference between them is , At compile time, the compiler does not perform type safety checks on the original types , However, the type with parameters will be checked , By using Object As a type , You can tell the compiler that the method can accept any type of object , such as String or Integer. The purpose of this question is to understand the primitive types in generics correctly . The second difference between them is , You can pass any generic type with parameters to accept the original type List Methods , But it can't put List<String> Pass it on to the receiver List<Object> Methods , Because there will be compilation errors .

12、Java in List<?> and List<Object> What's the difference ?

This question looks like the next one , In essence, it's totally different .List<?> It's an unknown type of List, and List<Object> It's actually any kind of List. You can take List<String>, List<Integer> Assign a value to List<?>, But I can't List<String> Assign a value to List<Object>.

List<?> listOfAnyType;
List<Object> listOfObject = new ArrayList<Object>();
List<String> listOfString = new ArrayList<String>();
List<Integer> listOfInteger = new ArrayList<Integer>();
listOfAnyType = listOfString; //legal
listOfAnyType = listOfInteger; //legal
listOfObjectType = (List<Object>) listOfString; //compiler error - in-convertible ty


13、List<String> And the original type List The difference between .

The problem is similar to “ What's the difference between a primitive type and a type with parameters ”. Types with parameters are type safe , And its type safety is guaranteed by the compiler , But the original type List But not type safe . You can't put String Any other type of Object Deposit in String Type of List in , And you can put any type of object in the original List in . Using generic parameterized types, you don't need to type cast , But for primitive types , You need to do an explicit type conversion .

List listOfRawTypes = new ArrayList();
listOfRawTypes.add(123); // The compiler allows this  -  There are exceptions at run time 
String item = (String) listOfRawTypes.get(0); // Need explicit type conversion 
item = (String) listOfRawTypes.get(1); // throw  ClassCastException, because  Integer  Can't be converted to  String
List<String> listOfString = new ArrayList();
listOfString.add(1234); // Compile error , Better than throwing exceptions at runtime 
item = listOfString.get(0); // No explicit type conversion is required  -  Compiler auto conversion 



Wildcard upper bound

Regular use

public class Test {
public static void printIntValue(List<? extends Number> list) {
for (Number number : list) {
System.out.print(number.intValue()+" ");
public static void main(String[] args) {
List<Integer> integerList=new ArrayList<Integer>();
List<Float> floatList=new ArrayList<Float>();
} }


Output :

2 2

3 0

Illegal use

public class Test {
public static void fillNumberList(List<? extends Number> list) {
list.add(new Integer(0));// Compile error 
list.add(new Float(1.0));// Compile error 
public static void main(String[] args) {
List<? extends Number> list=new ArrayList();
list.add(new Integer(1));// Compile error 
list.add(new Float(1.0));// Compile error 
} }


List<? extends Number> Can represent List<Integer> or List<Float>, Why can't we just add Integer perhaps Float Well ?

First , We know List<Integer> You can only add Integer. And the following code is feasible :

List<? extends Number> list1=new ArrayList<Integer>();
List<? extends Number> list2=new ArrayList<Float>();


Let's assume that the previous example has no compilation errors , If we put list1 perhaps list2 Incoming method fillNumberList, Obviously there will be type mismatches , Suppose not .

therefore , We come to a conclusion : You can't go to List<? extends T> Add any object to , except null.

So why is that right List<? extends T> It's OK to iterate , Because the subclass must have the same interface as the parent , This is exactly what we expect .

Wildcard lower bound

Regular use

public class Test {
public static void fillNumberList(List<? super Number> list) {
list.add(new Integer(0));
list.add(new Float(1.0));
public static void main(String[] args) {
List<? super Number> list=new ArrayList();
list.add(new Integer(1));
list.add(new Float(1.1));
} }


You can add Number Any subclass of , Why? ?

List<? super Number> Can represent List<T>, among T by Number Parent class ,( although Number No parent ). if ,T by Number Parent class of , We want to List<T> Add Number Subclasses of are certainly ok .

Illegal use

Yes List<? superT> Iteration is not allowed . Why? ? You know which interface to use to iterate List Do you ? Only with Object Class to ensure that all elements in the collection have the interface , Obviously it doesn't make much sense . The application scenarios are as follows .

*** wildcard

We know the upper and lower bounds of wildcards , Actually, it's the same as knowing *** wildcard , Without any modification , One by one “?”. Such as List<?>,“?” Can represent any type of ,“ arbitrarily ” That is, the unknown type .

List<Object> And List<?> It's not the same as ,List<Object> yes List<?> Subclasses of . And you can't go to List<?> list Add any object to the , except null.

Regular use

1、 When the method is original Object When type is used as a parameter , as follows :

public static void printList(List<Object> list) {
for (Object elem : list)
System.out.println(elem + "");


You can choose to implement it as follows :

public static void printList(List<?list) {
for (Object elem: list)
System.out.print(elem + "");


This allows for more output compatibility , It's not just List<Object>, as follows :

List<Integer> li = Arrays.asList(1, 2, 3);

List<String> ls = Arrays.asList("one""two""three");
本文为[osc_ ninety-one million nine hundred and fifty-eight thousand t]所创,转载请带上原文链接,感谢

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云