当前位置:网站首页>generic paradigm
generic paradigm
2022-07-27 15:12:00 【James-Tom】
1、 Definition
Generics are java1.5 The concept introduced in version .
There are two definitions :
1、 In the program code, some include Type parameter The type of , That is to say, parameters of generics can only represent classes , Can't represent individual objects .
2、 Some classes containing parameters in program coding . Its parameters can represent classes or objects and so on .
Whatever definition you use , The parameters of generics must be specified when they are used .
The above two definitions are not well understood , If you understand , Imagine that you can replace integers when defining 、 String type 、 A collection of object classes represents classes .
2、 Common terms
2.1、 Type Erasure
Here's the code , What will be output ?
List<String> sList = new ArrayList<>();
List<Integer> iList = new ArrayList<>();
System.out.println(sList.getClass() == iList.getClass());
Output results :
true
Generic information only exists in the code compilation stage , When entering JVM Before , Information about generics is erased , The technical term is type erasure .
about List and List In terms of their Class Type in the jvm Medium Class All are List.class. Generic type information is erased .
designated String and Integer Where is it reflected in the end ?
The answer is when the class compiles . When JVM Generic checking will be performed when compiling classes , If a collection is declared as String type , When it accesses data to the set, it will judge the data , So as to avoid storing or fetching the wrong data .
in other words : Generics exist only at compile time , It doesn't exist in the running phase . After compiling class In file , There is no concept of generics .
2.2、 wildcard
Rider<? extends Animal> rider1 = new Rider<Horse>();
Rider<? super Horse> rider4 = new Rider<Animal>();
In the previous code extends and super Keywords are generic wildcards .
Before introducing generic wildcards , You need to have a basic understanding of compile time types and runtime types , In order to better understand the use of wildcards .
Define a parent class first (Animal) And a subclass (Horse) :
public class Animal {
}
public class Horse extends Animal {
}
Create another Horse object
Horse horse = new Horse();
In the above code ,horse The object pointed to by the instance , Both compile time and runtime types are Horse type .
But sometimes we can use the following way
Animal horse1 = new Horse();
Use Animal A variable of type points to a Horse object , Because in java It is allowed to assign the object of a subclass directly to the reference variable of a parent class , We call it [ Upward transformation ].
But the problem is , here horse1 The object that the variable points to , What are the compile time and run-time types ?
The answer is :horse1 The object that the variable points to , Its type at compile time is Animal type , The type at runtime is Horse type .
Why is that ?
Because at compile time ,JVM Only know Animal Class variable points to an object , And this object is Animal Objects like or self objects , Its specific type is uncertain , It could be Horse, It could be Mule type . For the sake of safety ,JVM At this time will be horse1 The object pointed to by the variable is defined as Animal type . Because regardless of the fact Horse Type or Mule type , They can all safely turn into Animal type .
In the run-time phase ,JVM Through initialization, we know that it points to a Horse object , So the type at runtime is Horse type .
2.2.1、 Upward transformation
There is a parent class on it Animal And a subclass Horse, At this time, add another rider ,Rider class .Rider Class defines some basic behaviors :
public class Rider<T> {
private List<T> list;
public Rider() {
list = new ArrayList<T>();
}
public void ride(T item) {
list.add(item);
}
public T get() {
return list.get(0);
}
}
Riders Rider Class defines a T The generic type , Any type of , If a rider can ride a horse , Ride some animals , The main thing is to have the behavior of riding .
For example, define a rider , The code snippet is as follows :
Rider<Animal> rider=new Rider<Animal>();
For example, riders ride some animals , The code snippet is as follows :
rider.ride(new Animal());
rider.ride(new Horse());
according to java The principle of upward transformation , We can define a rider like this :
Rider<Animal> rider1=new Rider<Horse>();
But the above code will report errors when compiling :Incompatible types..
Logically speaking , This way of writing should be no problem , because java Support upward transformation .
The reason for the mistake is :java Upward transformation of generics is not supported , So you can't use the above writing .
But you can use Generic wildcard To solve this problem .
The correct code snippet is as follows :
Rider<? extends Animal> rider1 = new Rider<Horse>();
The above line of code identifies :Rider It can point to any Animal Class object , Or anything Aimal Subclass object of .
Horse yes Animal And so on , So it can be compiled normally .
2.2.2、extends Defects of wildcards
Though through extends Wildcards support java Upward transformation of generics , But this way is flawed , That's it : It cannot be directed Rider Add any object to , Only objects can be read from .
Rider<? extends Animal> rider1 = new Rider<Horse>();
rider1.ride(new Horse());// Compiler error
rider1.ride(new Mule());// Compiler error
Animal animal1 = rider1.get();// Compile successfully
You can see , When we let riders ride horses and mules , You will find compilation errors . But we can take the animal being ridden from it .
Then why can't we let riders ride animals ?
We have to start with our definition of rider .
Rider<? extends Animal> rider = new Rider<XXX>();
In the above definition of rider ,rider It can point to any Animal object , Or is it Animal Subclass object . in other words ,plate The object pointed to by the property can be Horse type , It can also be Mule type .
For example, the following code snippets are correct :
Rider<? extends Animal> rider1 = new Rider<Horse>();
Rider<? extends Animal> rider2 = new Rider<Mule>();
When there is no specific operation ,JVM I don't know what animals we want our riders to ride , Is it a horse or a mule , Have no idea . Since I'm not sure what animal to ride , that JVM Just don't let anything go , Avoid error .
In view of this , So when used extends When a wildcard is used , Nothing can be added to it .
But why can we extract data ?
Because whether it's a horse or a mule , Can be used through upward transformation Animal A variable of type points to it , This is in java Are allowed .
Animal animal1 = rider1.get();// Compile successfully
Horse horse1 = rider1.get();// Compile error
In the code snippet above , When using a Horse The variable of type points to a time when the object horse to be ridden is taken from the rider class , There will be an error .
So when used extends When a wildcard is used , You can take out everything .
summary , adopt extends Keywords can realize upward transformation . But it lost some flexibility , That is, nothing can be added to it , Only take out things .
2.2.3、super Defects of wildcards
And extends Wildcards are similar, while another wildcard is :super wildcard , Its characteristics and extends The opposite . There are also defects :super Wildcards can be stored in objects , But there are restrictions when taking out objects .
The use example fragment is as follows :
Rider<? super Horse> rider3 = new Rider<Horse>();
Rider<? super Horse> rider4 = new Rider<Animal>();
Rider<? super Horse> rider5 = new Rider<Object>();
The code above indicates :Rider Variables can point to a specific type of Rider object , As long as this particular type is Horse or Horse Parent class of .Object It's also Animal Parent class of , The same relationship can be inherited .
in other words rider5 The specific type of point can be Horse The father of ,JVM It is definitely impossible to determine which type it is when compiling . however JVM For sure , whatever Horse All subclasses of can be converted to Horse type , But any Horse The parent class of cannot be converted to Horse type .
So for using super Wildcards , We can only deposit T Type and T Subclass object of type .
rider4.ride(new Horse());
rider4.ride(new Warhorse());
rider4.ride(new Animal());// Compile error
When we introduced Horse Parent class of Animal Compilation errors will be reported when .
And when we take out the data , It's the same thing ,JVM Know when compiling , Our specific runtime type can be any Horse Parent class of , So for the sake of safety , We use a top-level parent to specify the retrieved data , In this way, cast exceptions can be avoided .
Object object = rider4.get();
Horse object = rider4.get();// Compile error
You can see from the code above , When using Horse A variable of type points to Rider Take out the object , There will be compilation errors , While using Objec A variable of type points to Rider Take out the object , Then you can pass .
That is to say, for using super Wildcards , We can only use it when we take it out Object The variable of type points to the extracted object .
3、 summary
1、 When your scenario is producer type , When resources need to be obtained for production , We recommend using extends wildcard , Because of the use of extends The type of wildcard is more suitable for obtaining resources .
2、 When your scenario is consumer type , When resources need to be stored for consumption , We recommend using super wildcard , Because use super The type of wildcard is more suitable for storing resources .
3、 If you want to deposit , I want to take it out again , Then you'd better not use extends or super wildcard .

WeChat official account : A dusty journey
There are a lot of things I want to say to you , It's like chatting with friends .
Write code , To do a design , Talking about life , Talk about work , Talk about the workplace .
What is the world I see ?
Search and follow me .
边栏推荐
- 多表查询_子查询概述和多表查询_子查询情况1&情况2&情况3
- lc marathon 7.26
- 通过VN1630/VN7640的I/O功能来确认电源设置电压的时间精确度
- Nefu119 combinatorial prime [basic theorem of arithmetic]
- LeetCode 190. 颠倒二进制位 位运算/easy
- HDU3117 Fibonacci Numbers【数学】
- Regular expressions: mailbox matching
- Introduction of the connecting circuit between ad7606 and stm32
- Design scheme of digital oscilloscope based on stm32
- CAN总线的EMC设计方案
猜你喜欢

移动端使用vantUI的list组件,多个tab项来回切换时,列表加载多次导致数据无法正常展示

基于FIFO IDT7202-12的数字存储示波器

如何做好企业系统漏洞评估

图解 SQL,这也太形象了吧

DIY制作示波器的超详细教程:(一)我不是为了做一个示波器

电子制造行业的数字化转型突破点在哪?精益制造是关键

USB2.0接口的EMC设计方案

STM32F103C8T6在Arduino框架下驱动SH1106 1.3“ IIC OLED显示

ADB command (install APK package format: ADB install APK address package name on the computer)

Lecture 4: Longest ascending substring
随机推荐
Zhou Hongyi: if the digital security ability is backward, it will also be beaten
【云享读书会第13期】多媒体处理工具 FFmpeg 工具集
初探STM32掉电复位PDR
基于stm32的数字示波器设计方案
谷歌团队推出新Transformer,优化全景分割方案|CVPR 2022
网络设备硬核技术内幕 路由器篇 17 DPDK及其前传(二)
网络设备硬核技术内幕 路由器篇 3 贾宝玉梦游太虚幻境 (中)
STM32学习之CAN控制器简介
积分运算电路的设计方法详细介绍
《剑指Offer》两个链表的第一个公共结点
LeetCode 341.扁平化嵌套列表迭代器 dfs,栈/ Medium
Stock trading 4
LeetCode 74. 搜索二维矩阵 二分/medium
网络设备硬核技术内幕 路由器篇 CISCO ASR9900拆解 (一)
lc marathon 7.26
STM32 can -- can ID filter analysis
Idea makes jar packages and introduces jar packages
Lesson 3: SPFA seeking the shortest path
Code coverage statistical artifact -jacobo tool practice
两阶段提交与三阶段提交