java写dnf外掛_dnf卡盟_Java的泛型详解(一)

Java实现DDD中UnitOfWorkdnf卡盟

Java的泛型详解

泛型的利益

编写的代码可以被差别类型的工具所重用。

由于上面的一个优点,泛型也可以削减代码的编写。

泛型的使用

简朴泛型类

public class Pair {

private T first;

private T second;

public Pair() {

first = null;

second = null;

}

public Pair(T first, T second){

this.first = first;

this.second = second;

}

public T getFirst(){

return first;

}

public T getSecond(){

return second;

}

public void setFirst(T first) {

this.first = first;

}

public void setSecond(T second) {

this.second = second;

}

}

上面例子可以看出泛型变量为T;

用尖括号(<>)括起来,并放在类名后面;

泛型还可以界说多个类型变量好比上面的例子 first和second差别的类型:

public class Pair {....}

注: 类型变量的界说需要一定的规范:

(1) 类型变量使用大写形式,而且要比较短;

(2)常见的类型变量稀奇代表一些意义:变量E 示意聚集类型,K和V示意要害字和值的类型;T、U、S示意随便类型;

类界说的类型变量可以作为方式的返回类型或者局部变量的类型;

例如: private T first;

用详细的类型替换类型变量就可以实例化泛型类型;

例如: Pair 代表将上述所有的T 都替换成了String

由此可见泛型类是可以看作通俗类的工厂

泛型方式

我们应该若何界说一个泛型方式呢?

泛型的方式可以界说在泛型类,也可以界说在通俗类,那若是界说在通俗类需要有一个尖括号加类型来指定这个泛型方式详细的类型;

public class TestUtils {

public static T getMiddle(T... a){

return a[a.length / 2];

}

}

类型变量放在修饰符(static)和返回类型的中心;

当你挪用上面的方式的时刻只需要在方式名前面的尖括号放入详细的类型即可;

String middle = TestUtils.getMiddle("a", "b", "c");

若是上图这种情形实在可以省略 ,由于编译器能够推断出挪用的方式一定是String,以是下面这种挪用也是可以的;

String middle = TestUtils.getMiddle("a", "b", "c");

然则若是是以下挪用可能会有问题:

qY7Jbu.png

如图:可以看到变意思没有办法确定这里的类型,由于此时我们入参通报了一个Double3.14 两个Integer1729 和0 编译器以为这三个不属于同一个类型;

此时有一种解决办法就是把整型写成Double类型

uMjMZb.png

类型变量的限制

有时刻我们不能无限制的让使用者通报随便的类型,我们需要对我们泛型的方式举行限制通报变量,好比如下例子

盘算数组中最下的元素

YVRVRr.png

这个时刻是无法编译通过的,且编译器会报错

由于我们的编译器不能确定你这个T 类型是否有compareTo这个函数,以是这么能让编译器信赖我们这个T是一定会有compareTo呢?

我们可以这么写 这里的意思是T一定是继续Comparable的类

由于Comparable是一定有compareTo这个方式,以是T一定有compareTo方式,于是编译器就不会报错了

由于加了限制那么min这个方式也只有继续了Comparable的类才可以挪用;

若是要限制方式的泛型继续多个类可以加extends 要害字并用&支解如:T extends Comparable & Serializable

限制类型是用&支解的,逗号来支解多个类型变量

类型擦除

岂论什么时刻界说一个泛型类型,虚拟机都市提供一个响应的原始类型(raw type)。原始类型的名字就是删掉类型参数后的泛型类型。擦除类型变量,并替换限制类型(没有限制类型的变量用Object)

列如: Pair 的原始类型如下所示

public class Pair {

private Object first;

private Object second;

public Pair() {

first = null;

second = null;

}

public Pair(Object first, Object second){

this.first = first;

this.second = second;

}

public Object getFirst(){

return first;

}

public Object getSecond(){

return second;

}

public void setFirst(Object first) {

this.first = first;

}

public void setSecond(Object second) {

this.second = second;

}

}

由于上面的T是没有限制变量,于是用Object取代了;

若是有限制变量则会以第一个限制变量替换为原始类型如:

public class Interval implements Serializable{

private T lower;

private T upper;

}

原始类型如下所示:

public class Interval implements Serializable{

private Comparable lower;

private Comparable upper;

}

翻译泛型表达式

上面说到泛型擦除类型变量后对于无限制变量后会以Object来替换泛型类型变量;

然则我们使用的时刻并不需要举行强制类型转换;

原因是编译器已经强制插入类型转换;

例如:

Pair buddies = ...;

Employee buddy = buddies.getFirst();

擦除getFirst的返回类型后将返回Object类型,然则编译器自动插入Employee的强制类型转换,编译器会把这个方式挪用翻译为两条虚拟机指令;

对原始方式Pair.getFirst的挪用

将返回的Object类型强制转换为Employee类型;

我们可以反编译验证一下

YrAjqy.png

要害的字节码有以下两条

9: invokevirtual #4 // Method com/canglang/Pair.getFirst:()Ljava/lang/Object;

12: checkcast #5 // class com/canglang/model/Employee

虚拟机指令寄义如下:,dnf论坛,

invokevirtual:虚函数挪用,挪用工具的实例方式,凭据工具的现实类型举行派发,支持多态;

checkcast:用于检查类型强制转换是否可以举行。若是可以举行,checkcast指令不会改变操作数栈,否则它会抛出ClassCastException异常;

由此我们可以验证了上述的结论,在反编译后的字节码中看到,当对泛型表达式挪用时,虚拟机操作如下:

对于工具的现实类型举行替换泛型;

检查类型是否可以强制转换,若是可以将对返回的类型举行强制转换;

翻译泛型方式

类型擦除也会出现在泛型方式内里

public static T min(T[] a)

类型擦除后

public static Comparable min(Comparable[] a)

此时可以看到类型参数T已经被擦除了,只剩下限制类型Comparable;

方式的类型擦除带来了两个庞大的问题,看下面的示例:

public class DateInterval extends Pair {

public void setSecond(LocalDate second){

System.out.println("DateInterval: 进来这里了!");

}

}

此时有个问题,从Pair继续的setSecond方式类型擦除后为

public void setSecond(Object second)

这个和DateInterval的setSecond显著是两个差别的方式,由于他们有差别的类型的参数,一个是Object,一个LocalDate;

那么看下面一个列子

public class Test {

public static void main(String[] args) {

DateInterval interval = new DateInterval();

Pair pair = interval;

pair.setSecond(LocalDate.of(2020, 5, 20));

}

}

Pair引用了DateInterval工具,以是应该挪用DateInterval.setSecond。

我们看一下运行效果

EJviQb.png

然则看了反编译的字节码可能发现一个问题:

17: invokestatic #4 // Method java/time/LocalDate.of:(III)Ljava/time/LocalDate;

20: invokevirtual #5 // Method com/canglang/Pair.setSecond:(Ljava/lang/Object;)V

这里可以看到此处字节码挪用的是Pair.setSecond

这里有个主要的观点就是桥方式

引用Oracle中对于这个征象的注释

为了解决此问题并在类型擦除后保留通用类型的 多态性,

Java编译器天生了一个桥接方式,以确保子类型能够按预期事情。

对于DateInterval类,编译器为setSecond天生以下桥接方式:

public class DateInterval extends Pair {

// Bridge method generated by the compiler

//

public void setSecond(Object second) {

setSecond((LocalDate)second);

}

public void setSecond(LocalDate second){

System.out.println("DateInterval: 进来这里了!");

}

}

那么我们若何验证是否天生这个桥方式呢?我们可以反编译一下DateInterval.java看一下字节码;

public void setSecond(java.lang.Object);

descriptor: (Ljava/lang/Object;)V

flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

Code:

stack=2, locals=2, args_size=2

0: aload_0

1: aload_1

2: checkcast #5 // class java/time/LocalDate

5: invokevirtual #6 // Method setSecond:(Ljava/time/LocalDate;)V

8: return

我截取了部门发现在 DateInterval的字节码中简直会有一个桥方式,同时验证了上面的问题;

总结:

虚拟机中没有泛型,只有通俗的类和方式

所有的类型参数都用他们的限制类型替换

桥方式被合成来保持多态

为保持类型安全性,必要时插入强制类型转换,dnf助手Kubernetes学习笔记(二):Pod、标签、注解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++set容器-大小和交换

set大小和交换 功能描述&#xff1a; 统计set容器大小以及交换set容器 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <set> //set容器 大小和容器void printSet(set<int > &s) {for (set<int …

Asp.Net Core下的开源任务调度平台ScheduleMaster—快速上手

概述ScheduleMaster是一个开源的分布式任务调度系统&#xff0c;它基于Asp.Net Core平台构建&#xff0c;支持跨平台多节点部署运行。它的项目主页在这里&#xff1a;https://github.com/hey-hoho/ScheduleMasterCore关于它的简单介绍可以看这里&#xff1a;https://www.cnblog…

C++set容器-插入和删除

set插入和删除 功能描述&#xff1a; set容器进行插入数据和删除数据 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <set>void printSet(set<int > &s) {for (set<int >::iterator it s.be…

基于Jenkins的持续交付全流程设计与实践

1 从理论开始什么是DevOps?近年来&#xff0c;随着DevOps理念的逐渐深入人心&#xff0c;企业逐渐意识到从看似重复的手工劳动中实现自动化流程处理&#xff0c;对于提高企业劳动生产力已经非常重要&#xff0c;尤其是面向互联网的开发者&#xff0c;往往每次上线时&#xff0…

C++set容器-查找和统计

set查找和统计 功能描述&#xff1a; 对set容器进行查找数据以及统计数据 函数原型&#xff1a; 代码如下: #include <iostream> using namespace std; #include <set>//set查找和统计void test01() {//查找set<int >s1;//插入数据s1.insert(10);s1.inse…

C++set和multiset区别

区别&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <set>//set容器 和multiset容器的区别 void test01() {set<int >s;pair<set<int >::iterator, bool> ret s.insert(10);if (ret.second) {cout &…

.NET CORE(C#) WPF简单菜单MVVM绑定

阅读导航 本文背景 代码实现 本文参考 源码 1. 本文背景 WPF中垂直导航菜单大家应该都常用&#xff0c;本文介绍使用MVVM的方式怎么绑定菜单&#xff0c;真的很简单。 2. 代码实现 使用 .Net Core 3.1 创建名为 “MenuMVVM” 的WPF模板项目&#xff0c;添加两个Nuget库&…

C++pair对组的创建

pair对组创建 功能描述&#xff1a; 成对出现的数据&#xff0c;利用对组可以返回两个数据 两种创建方式&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <cstring>void test01() {//第一种方式pair<string, int>…

避免在 ASP.NET Core 3.0 中为启动类注入服务

本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇。 Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostingEnvironment VS IHostEnvironent - .NET Core 3.0 中的废弃类型 Part 3 - 避免在 ASP.NET Core 3.0 中为启动类注入服务&#xff08;本篇&…

C++set容器-内置类型指定排序

set容器排序 利用访函数&#xff0c;可以改变排序规则 一、set存放内置数据类型 代码如下&#xff1a; #include <iostream> using namespace std; #include <set>class Mycompare {public:bool operator()(int v1, int v2) {return v1 > v2;} };//set容器排序…

workman php 安装,workerman安装及遇到的问题解决

下面由workerman入门教程栏目给大家介绍workerman安装及遇到的问题解决方法&#xff0c;希望对需要的朋友有所帮助&#xff01;1、workerman安装workerman是php的一个socket框架&#xff0c;简化了socket编程&#xff0c;已经为很多企业所用&#xff0c;今天在centos的ngixphp下…

.NET CORE(C#) WPF亚克力窗体

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff1a;请网站留言&#xff0c; 如果对您有所帮助&#xff1a;欢迎赞赏。.NET CORE(C#) WPF亚克力窗体阅读导航本文背景代码实现本文参考源码1. 本文背景本文介绍使用FluentWPF控…

C++map容器-构造和赋值

map基本概念 map构造和赋值 功能描述&#xff1a; 对map容器进行构造和赋值操作 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; //map容器 构造和赋值 #include <map>void printMap(map<int, int> &m) {fo…

ABP框架v2.0 和 ABP商业版

ABP框架2.0版已经在本周公布.这篇文章解释了为什么我们发布了一个抢先主版本,和2.0版本中的变化.除了v2.0版本,我们很高兴地宣布ABP商业版,这是建立在开源ABP框架的之上的一套专业的模块,工具,主题和服务.ABP框架V2.0为什么2.0,而不是1.2&#xff1f;本来在V1.1.2发布后计划发布…

C++map容器-大小和互换

map大小和互换 功能描述&#xff1a; 统计map容器大小以及交换map容器 函数原型&#xff1a; 代码如下&#xff1a; #include <iostream> using namespace std; #include <map>//map容器 大小和交换 void test01() {map<int, int>m;m.insert(pair<in…

分享一些提高逻辑能力的心得

大家好&#xff0c;我是Z哥。最近有个很明显的感受。就是随着年龄的增长&#xff0c;我越来越发现曾经一些我认为理所应当的事情&#xff0c;在现在看来是如此的傻&#xff0c;如此的没有逻辑。有一句话是这么说的。花半秒钟就看透事物本质的人&#xff0c;和花一辈子都看不清事…

php 配置远程调试,PHP Linux 环境下搭建 XDEBUG并配置远程调试

在网站 https://xdebug.org/download.php 找到对应PHP版本的XDEBUG下载&#xff0c;下载时选择source版本image获取下载地址## 下载打包的源码wget https://xdebug.org/files/xdebug-2.5.5.tgz解包tar zxvf xdebug-2.5.5.tgz进入解包后的源码目录cd xdebug-2.5.5执行 phpize 生…

CAP原理

定义在一个分布式系统&#xff08;指系统中的节点互相连接并共享数据&#xff09;中&#xff0c;当涉及读写操作时&#xff0c;只能保证一致性 (Consistency)、可用性 (Availability)、分区容错性 (Partition Tolerance)三者中的两个&#xff0c;另外一个必须被牺牲。一致性&am…

大学生开题报告php,php毕业设计开题报告

php毕业设计开题报告该频道涵盖有关于开题报告和毕业设计的论文范例,免费教你怎么写php毕业设计论文提供相关参考资料。一、研究背景1 基于英语新课程标准的要求。《英语课程标准》指出&#xff1a;必须正视学生外语学习基础和发展要求的差异&#xff0c;遵循外语学习的客观规律…

服务器应用服务为何卡顿?原来是内存耗尽惹的祸!

做过运维的朋友们都可能会遇到&#xff1a;服务器应用程序运行慢的问题&#xff0c;最终各部门找上门&#xff0c;。今天在这我跟大家分享一个案例及其解决办法。以前我跟很多朋友们也为这样的事情苦恼过&#xff0c;我的服务器内存可是64G啊&#xff0c;这都不够它吃的。后来我…