java中的single_解析java泛型(一)

对于我们java中的泛型,可能很多人知道怎么使用并且使用的还不错,但是我认为想要恰到好处的使用泛型,还是需要深入的了解一下它的各种概念和内部原理。本文将尽可能的囊括java泛型中的重要的概念。主要内容如下:泛型的定义及为什么要使用泛型

定义一个简单的泛型类

定义一个简单的泛型方法

类型参数的限定

泛型内部实现的基本原理

泛型通配符(难点)

泛型的其他实现细节

一、何谓泛型

泛型程序设计意味着编写的代码可以被不同中类型的对象重用。例如:MyList,MyList是一种类型,MyList也是一种类型,但是使用的代码块都是MyList,这也就是java中引入泛型的一种原因:可以增强代码的复用性,当然这种限定死类型的方式也会使得代码的安全性和可读性更高。

二、一个简单的泛型类

先看一个完整的泛型类:/*一个简单的泛型类的声明如下*/

public class Pair {

private T a;

private T b;

public Pair(T a, T b){

this.a = a;

this.b = b;

}

}

由此可以看出来,泛型类型和普通类型的区别主要在于:类名之后多了个,并且实例域类型可以不是具体的类型而是不确定的T类型。其中,我们管T叫做类型变量,类型变量一般使用大写字母表示并且很短(在java中使用E表示集合的元素类型,K和V分别表示关键字和值的类型)。

使用具体的类型来替换类型变量的过程我们叫做实例化泛型类型。例如:Pair,等。这其中需要注意的是:java中的9中基本类型是不能作为类型变量的,也就是:Pair,是会不允许的。当然,声明一个泛型类时,不局限于一个类型变量,可以由多个类型变量,例如:/*声明两个类型变量也是可以的*/

public class Pair {

private T a;

private U b;

public Pair(T a, U b){

this.a = a;

this.b = b;

}

}

//Pair p new Pair<>("abc",12);

//创建泛型类实例变量的时候,可以省略类型变量,编译器可以推测出来

三、一个简单的泛型方法

怎么定义泛型类,我们已经介绍过了,接下来我们一起看看泛型方法是如何定义和调用的。/*泛型类中定义了一个泛型方法*/

public class Pair {

//声明一个泛型方法

public T getA(T c){

return c;

}

}

/*main函数中调用泛型方法*/

public class Test2 {

public static void main(String[] args){

Pair p = new Pair(1,2);

//调用泛型方法

System.out.println(p.show(10));

}

}

我们可以看到,声明一个泛型方法:public T getA(T c),放在返回值前面,修饰符后面,T表示返回类型。泛型方法的调用:p.show(10),在方法名前面放置类型变量,当然也可以选择省略,当编译器没有足够的信息推测出来时就会报错,那时你再添加也不迟(但是,如果你能减轻计算机的工作的话,想必是可以提高效率的)

小结一下,泛型类和泛型方法。泛型类中可以声明泛型方法也可以声明普通方法,泛型方法可以出现在泛型类中也可以出现在普通类中,也就是它们之间并没有什么约束关系。四、类型变量的限定

前面我们已经知道了什么是类型变量,我们看一段代码:public class Pair {

public static int myCompare(T a,T b){

return a.compareTo(b);//此处编译不通过

}

}

我们知道,如果想要使用compareTo方法,就要实现Comparable接口,或者继承实现了此接口的类。此处想要使得程序正确,有两种办法。第一种:使类继承Comparable接口并且实现compareTo方法。第二种:就是使用类型变量限定。如下:/*限定变量类型*/

public class Pair {

public static int myCompare(T a,T b){

return a.compareTo(b);

}

}

细心的同学可能已经发现,相比于原来的方法,就是使类型变量继承与Comparable接口。原来的变成了,表示:原来的T可以是任意类型的,而现在的T被限制必须实现了Comparable 接口,就是说,凡是使用此泛型的类都是直接或者间接继承了Comparable 接口并实现其中方法的。所以,一旦我们将T限定了,就不用考虑实现Comparable 接口的事情了,程序的封装性更强了。

对类型变量的限定可以由多个限定,它们之间使用&分隔,而使用逗号分隔类型变量。看个例子:

//一个类型变量的一个类型限定

//一个类型变量的两个类型限定

//两个类型变量的类型限定

五、泛型实现的基本原理

讨论了这么多的泛型方法,泛型类以及各种使用技巧,接下来,我们一起看看虚拟机实际执行时是怎么对待我们的泛型的。我们都知道java中有编译器和虚拟机,但实际上我们的泛型在这两者看来是不一样的,也就是说,虚拟机是不认识泛型的,而只有我们强大的编译器是认识泛型的。那他们是怎么实现统一的呢?接下来我们详细来看。

在java中,无论何时定义了一个泛型,它都会自动生成一个相应的原始类型。我们叫这个过程为:类型擦除。例如下面的代码:/*这是一段泛型类的代码*/

public class Pair {

private T a;

private T b;

public T getA(){

return this.a;

}

public T getB(){

return this.b;

}

}

经过类型擦除之后生成原始类型:

public class Pair{

private Object a;

private Object b;

public Object getA(){

return this.a;

}

public Object getB(){

return this.b;

}

}

经过对比,我们可以得出结论:去除了泛型的标志性符号<>并且所有的T类型都被替换成Object类型了。难道我们的类型擦除就是将所有的未知类型转换为Object类型吗?当然不是,类型擦除是有规则的而不是一味的将未知类型T转换成Object类型的。

对于有限定的类型变量就将用类型变量的第一个限定类型替换。如:Pair,就会选择用Comparable替换所有的T并去除修饰在类后面的泛型符号,生成原始类型。

对于没有限定类型的类型变量就默认使用Object替换类型变量。例如:Pair就会使用Object替换所有的T类型变量。

最后小结一下,类型擦除针对是否有类型限定类型,根据不同的状况进行替换生成相应的原始类型供jvm调用。未完,待续。。。。

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

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

相关文章

java面板中添加面板_如何把窗体加入面板中 java

展开全部一般来说,我们常把JPanel[面板]放到JFrame窗体中但是也有一种内部窗体JInternalFrame ,可以放到其他的容器JDesktopPane里,效果图e69da5e887aa62616964757a686964616f31333363373731如下代码如下import java.awt.*;import java.awt.event.*;import java.beans.Property…

mysql 如果存在修改_mysql如存在并发修改可能,一定要注意保证数据一致性

近日&#xff0c;因人员调整接手了一个其他部门负责的项目。随后发现其中的很多关键环节是没有考虑mysql并发操作的&#xff0c;现列出存在的一例问题 并分享如何解决的。问题描述&#xff1a;用户账户余额转移赠送 (用户A将自己的账户剩余金额赠送给用户B),同一时刻还可能存在…

python prt_Python中的self

self代表类的实例&#xff0c;而非类。实例来说明Python1234567classTest:defprt(self):print(self)print(self.__class__)tTest()t.prt()执行结果如下Python12从上面的例子中可以很明显的看出&#xff0c;self代表的是类的实例。而self.class则指向类。self不必非写成self有很…

微信对账单 java_微信支付对账,你是如何处理的?

支付对账&#xff0c;即检查第三方支付与数据库中账单是否一一对应&#xff0c;涉及到微信对账单的处理&#xff0c;成功时&#xff0c;微信账单接口返回数据以文本表格的方式返回&#xff0c;第一行为表头&#xff0c;后面各行为对应的字段内容&#xff0c;字段内容跟查询订单…

java技术文章在哪里看呢_谈论Java技术似乎无处不在,但究竟是什么呢?文章末尾有福利...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼谈论Java技术似乎无处不在&#xff0c;但究竟是什么呢&#xff1f;下面的部分将解释Java技术如何既是一种编程语言&#xff0c;又是一种平台&#xff0c;并概述这种技术可以为您做些什么。Java编程语言是一种高级语言&#xff0c;可…

java中常用的关键字_java中的常用的关键字

在java编程过程中&#xff0c;会经常写到一些关键字&#xff0c;但是对于他们应用的方式其实一直是模仿状态&#xff0c;并没有很实质的去了解&#xff0c;为什么要这么用&#xff0c;导致程序不能优化&#xff0c;或者出现了bug不明所以&#xff0c;因而再详细的去重温了一下各…

java如何处理灰度图片_Java图片的灰度处理方法

通过看网上各种大牛的总结&#xff0c;和自己亲身测试总结一下Java图片的灰度处理方法(1)我们熟知的图片中的像素点有RGB值。(2)图片灰度化的方式大概分为四种&#xff0c;第一种是最大值法(取颜色RGB中的最大值作为灰度值)&#xff1b;第二种是最小值法(取颜色RGB的最小值作为…

java多项式和_在Java中查找多项式的根

小编典典请找到以下相同的示例示例public class PolynomialRootFinder {/*** * Given a set of polynomial coefficients, compute the roots of the polynomial. Depending on* the polynomial being considered the roots may contain complex number. When complex numbers …

java7 nio2 新特性_JDK7新特性,你知道几个?

前言之前学习的过程中&#xff0c;每天都是老师说这个是JDK7以后可以使用&#xff0c;那个是JDK8以后可以使用&#xff0c;每天都记的很混乱&#xff0c;今天专门忙里偷闲&#xff0c;归拢整理下JDK7的新特性&#xff0c;对于JDK的新特性&#xff0c;后期会进行整理更新&#x…

java jsp校验提示信息_java Jquery表单校验代码jsp页面

jsp.file欢迎注册EasyMall/* 注册表单的js校验 */var formObj {/* 检查输入项是否为空 */"checkNull" : function(name, msg){var value $("input[name"name"]").val().trim();//清空之前的提示消息formObj.setMsg(name, "");if(val…

错误处理方法 java_JAVA常见错误处理方法 和 JVM内存结构

OutOfMemoryError在开发过程中是司空见惯的&#xff0c;遇到这个错误&#xff0c;新手程序员都知道从两个方面入手来解决&#xff1a;一是排查程序是否有BUG导致内存泄漏&#xff1b;二是调整JVM启动参数增大内存。OutOfMemoryError有好几种情况&#xff0c;每次遇到这个错误时…

java中如何分隔字符串_Java中分割字符串

java.lang.String的split()方法, JDK 1.4 or laterpublic String[] split(String regex,int limit)示例代码public classStringSplit {public static voidmain(String[] args) {String sourceStr "1,2,3,4,5";String[] sourceStrArray sourceStr.split(",&quo…

typescript 接口 java_Typescript基础(4)——接口

前言今天继续typescript的学习&#xff0c;开始ts接口部分的学习。接口接口的理解首先&#xff0c;我们谈论一下现实生活中的接口。比如生活中常用的插座接口&#xff0c;有些插头是三孔插座的&#xff0c;有些是两孔插座的。插座接口规定了插头的数目&#xff0c;那么我们的电…

php测试号推送消息失败,信息发送失败是什么原因

手机突然信息发送失败可能是以下原因&#xff1a;1.是因为我们的手机出现了欠费的情况,所以发不出短信,这种情况是最为普遍的,需要我们及时的进行缴费。2.手机的信息中心的号码设置有误,应该根据你所在省份的实际信息中心号码进行设置,这样一般就能解决这方面的问题。可能是你的…

php ajax 概率 转盘,php+jquery实现转盘抽奖 概率可任意调

phpjquery实现转盘抽奖 概率可任意调phpjquery实现转盘抽奖 概率可任意调Posted by: xiaomiao 2014/05/13in Code, PHP 3 Commentsphpjquery实现转盘抽奖查看DEMO演示转盘抽奖&#xff0c;炫丽的一般是flash做的。不懂flash而又不需要那么炫丽&#xff0c;可以简单的通过jquer…

组件php53 php55区别,分享下php5类中三种数据类型的区别

public: 公有类型    在子类中可以通过self::var 来调用 public类型的方法或属性 可以通过parent::method 来调用父类中的方法在实例中可以能过$obj->var 来调用 public类型的方法或属性protected: 受保护类型在子类中可以通过self::var 来调用 protected类型的方法…

wins宝塔安装提示已经有php,centOS安装宝塔提示报错

安装宝塔提示这个错误、一般是DNS问题、或者更换个安装节点P rootlocalhost:~root0104.223.166.114s password: ILast failed login: Tue Jul 17 02:32:19 EDT 2018 from 112.85.42.197 on. ssh :notty IThere were 780 failed login attempts since the last successful login…

php自动抓取文章图片,从文章中提取图片,把图片保存到本地,自动提取缩略图...

开发二代旅游网站程序和CMS的时候&#xff0c;有一个需求&#xff0c;就是从网上复制的内容&#xff0c;里面包含图片的&#xff0c;需要对把图片提取出来&#xff0c;并且保存到本地&#xff0c;并且把图片的URL地址本地化&#xff0c;以下是实现的代码。开发二代旅游网站程序…

url get参数 php,怎么取得Url中Get参数

这次给大家带来怎么取得Url中Get参数&#xff0c;取得Url中Get参数的注意事项有哪些&#xff0c;下面就是实战案例&#xff0c;一起来看一下。此时可以使用js的方式得到当前页面的url中的get参数. 核心语句是:window.location.href详细代码不解释了,有注释,你看了就懂.封装成jQ…

php tls,使用TLS在PHP中建立连接

我为特殊目的编写了一个小型SIP客户端.基本上,它使用函数fsockopen()连接到端口5060$fp fsockopen("10.0.0.1", 5060, $errno, $errstr, 30);然后基本上使用fread()和fwrite()读写SIP命令.现在,我的SIP服务操作符希望我们的客户使用SIPS,基本上是通过TLS的SIP.我花了…