- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java泛型定义与用法实例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了java泛型定义与用法。分享给大家供大家参考,具体如下:
。
先看如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import
java.util.list;
import
java.util.arraylist;
public
class
testgeneric {
@suppresswarnings
({
"rawtypes"
,
"unchecked"
})
public
static
void
main(string[] args) {
list list =
new
arraylist();
list.add(
1
);
list.add(
"1"
);
list.add(
new
object());
system.out.println(list);
// 取值
integer var1 = (integer) list.get(
0
);
string var2 = (string) list.get(
1
);
object var3 = list.get(
2
);
system.out.println(var1 +
" "
+ var2 +
" "
+ var3);
}
}
|
运行结果:
[1, 1, java.lang.object@1db9742] 1 1 java.lang.object@1db9742 。
这段代码很简单,将整形、字符串、对象放进list集合中,然后逐一取出。可以看出,由于list接口在定义时并不知道元素的类型,因此默认为object,即任意类型元素进入list集合后都会自动装箱。而取值的过程更为复杂,所有取得的值都是装箱后的object对象,必须得知道每一个元素的初始类型才能拆箱。一般使用集合的时候,集合的元素往往都是具有共同特征的,比如同属于一类的----那么,如果一开始限定了list集合元素的类型,那么就可避免上述不规范操作。代码如下, 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
java.util.list;
import
java.util.arraylist;
public
class
testgeneric {
@suppresswarnings
(
"unused"
)
public
static
void
main(string[] args) {
list<string> list =
new
arraylist<string>();
// list.add(1);//报错
// list.add(new object());//报错
list.add(
"1"
);
// 取值
string var1 = list.get(
0
);
// 无需转换
}
}
|
如此一来,便有了泛型集合的说法。实际上,查阅list接口的api会发现,list接口正是泛型接口,它可以接受一个类型参数e,若不传递参数,则默认是object类型.
。
有如下功能的代码,实现打印任意集合的元素:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
java.util.list;
import
java.util.arraylist;
import
java.util.collection;
public
class
testgeneric{
//打印任意集合元素
public
void
print(collection<object> c){
system.out.println(c);
}
public
static
void
main(string[] args){
list<string> list=
new
arraylist<string>();
new
testgeneric().print(list);
}
}
|
输出:
testgeneric.java:11: 无法将 testgeneric 中的 print(java.util.collection<java.lang.object>) 应用于 (java.util.list<java.lang.string>) new testgeneric().print(list); ^ 1 错误 。
很明显,意思就是传递的参数类型不匹配。难道string不是继承自object的吗?没错,string是继承自object的,但是list<string>与list<object>是截然不同的两个类型,两者之间没有任何继承关系。那如果真的要实现上面的功能,该如何呢?
2.1 类型通配符 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
java.util.list;
import
java.util.arraylist;
import
java.util.collection;
public
class
testgeneric {
// 打印任意集合元素
public
void
print(collection<?> c) {
system.out.println(c);
}
public
static
void
main(string[] args) {
list<string> list =
new
arraylist<string>();
new
testgeneric().print(list);
}
}
|
程序正常执行,这里的?表示一个未知类型,这个未知类型与object不同,list<?>代表了所有的list<类型>的父类.
2.2 泛型方法 。
不只有通配符可以解决泛型继承的问题,若将上面的方法定义为泛型方法也具有同样的效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
java.util.list;
import
java.util.arraylist;
import
java.util.collection;
public
class
testgeneric {
// 打印任意集合元素
public
<t>
void
print(collection<t> c) {
system.out.println(c);
}
public
static
void
main(string[] args) {
list<string> list =
new
arraylist<string>();
new
testgeneric().print(list);
}
}
|
泛型方法的定义形式如下, 。
修饰符 <t,e> 返回值 方法名(形参) 。
其中<t,e>在修饰符的后面做为类型定义,为方法指明形参中需要用到的t,e类型是来自哪里。既然泛型方法和类型通配符都可以实现泛型中的继承,那么有什么区别?
2.3 泛型方法和通配符的区别 。
看如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
import
java.util.list;
import
java.util.arraylist;
import
java.util.collection;
public
class
testgeneric {
// 打印任意集合元素
public
<e, t
extends
e>
void
print(collection<t> c1, collection<e> c2) {
system.out.println(c1);
system.out.println(c2);
}
public
static
void
main(string[] args) {
list<father> list1 =
new
arraylist<father>();
list<father> list2 =
new
arraylist<father>();
new
testgeneric().print(list1, list2);
// 传2个father类型
list<child> list3 =
new
arraylist<child>();
list<father> list4 =
new
arraylist<father>();
new
testgeneric().print(list3, list4);
// t为child,e为father
list<father> list5 =
new
arraylist<father>();
list<child> list6 =
new
arraylist<child>();
new
testgeneric().print(list5, list6);
// t为father,e为child,报错
}
}
class
father {
}
class
child
extends
father {
}
class
other {
}
|
上述泛型方法在定义t,e时已经指明了关系:t是e的子类,所以在传递参数的时候,t要么是e的子类,要么就是e本身,所以在传递关系不小心变为e exends t时,在第三次调用方法时报错了。而如果把上述代码换成?通配符的话,则不具有如此强的限定关系.
总之,泛型方法和?通配符都可以实现未知类型的继承,但是泛型方法主要强调多个未知类型之间的依赖关系。如果只是单纯用作成为一个通用类型的父类这一功能的话,两者都可以实现,反而?通配符较为简洁明了.
2.4 泛型参数上、下限的注意 。
看如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import
java.util.list;
import
java.util.arraylist;
import
java.util.collection;
public
class
testgeneric {
// 复制集合并返回原始集合的最后一个元素
public
<t> t copy(collection<t> des, collection<?
extends
t> src) {
t lastelement =
null
;
for
(t t : src) {
lastelement = t;
des.add(t);
}
return
lastelement;
}
public
static
void
main(string[] args) {
list<number> des =
new
arraylist<number>();
list<integer> src =
new
arraylist<integer>();
src.add(
new
integer(
1
));
integer lastelement =
new
testgeneric().copy(des, src);
//
system.out.println(lastelement.getclass());
}
}
|
输出:
testgeneric.java:18: 不兼容的类型 找到: java.lang.number 需要: java.lang.integer integer lastelement= new testgeneric().copy(des,src);// ^ 1 错误 。
当调用完copy方法后,系统比对发现t类型为number,?类型为integer。所以函数返回的t类型是number了,所以根本不兼容integer。要修改上面的代码,有俩个办法, 。
方法1:
改为 。
1
|
number lastelement=
new
testgeneric().copy(des,src);
|
分析代码可以得出,?为t的子类,在方法中t=lastelement这句表现为多态,虽然返回的是t类型,但是多态的表现为?类型,即interger类型,调用lastelement.getclass()也可发现返回的是java.lang.integer类型,说明此处编译类型为t类型,实际运行类型为?类型。这就好比如下多态转换, 。
1
2
|
father f=
new
child();
child c=f;
//此处一定报错,类型不兼容
|
虽然f的多态表现为子类child,但是上面一句连语法检测都过不了。这也就是为什么上面integer不能兼容number的原因了.
方法2:
改为 。
1
|
public
<t> t copy(collection<?
super
t> des,collection<t> src)
|
这样一来,?类型变为了父类,t类型变为了子类,于是在方法中返回的t类型对象,即lastelement就不具有多态性了。泛型中的上下限是很有学问的,每次看源码时都会琢磨很久,但还是会在浩瀚的接口+泛型的设计中昏迷,这种设计真的完全是为了突出面向对象的特性,以后慢慢琢磨吧.
从这也再次可以看出?通配符在处理具有依赖关系的泛型方法中,显得过于灵活而会导致一些潜在的隐患.
希望本文所述对大家java程序设计有所帮助.
原文链接:https://blog.csdn.net/kkkkkxiaofei/article/details/18262049 。
最后此篇关于Java泛型定义与用法实例详解的文章就讲到这里了,如果你想了解更多关于Java泛型定义与用法实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
全称“Java Virtual Machine statistics monitoring tool”(statistics 统计;monitoring 监控;tool 工具) 用于监控虚拟机的各种运
主要是讲下Mongodb的索引的查看、创建、删除、类型说明,还有就是Explain执行计划的解释说明。 可以转载,但请注明出处。  
1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发。 2>循环服务器和并发服务器
详解 linux中的关机和重启命令 一 shutdown命令 shutdown [选项] 时间 选项: ?
首先,将json串转为一个JObject对象: ? 1
matplotlib官网 matplotlib库默认英文字体 添加黑体(‘SimHei')为绘图字体 代码: plt.rcParams['font.sans-serif']=['SimHei'
在并发编程中,synchronized关键字是常出现的角色。之前我们都称呼synchronized关键字为重量锁,但是在jdk1.6中对synchronized进行了优化,引入了偏向锁、轻量锁。本篇
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。  
实例如下: ? 1
1. MemoryCahe NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型;提供了泛型支持;可以读缓存和单个缓存
argument是javascript中函数的一个特殊参数,例如下文,利用argument访问函数参数,判断函数是否执行 复制代码 代码如下: <script
一不小心装了一个Redis服务,开了一个全网的默认端口,一开始以为这台服务器没有公网ip,结果发现之后悔之莫及啊 某天发现cpu load高的出奇,发现一个minerd进程 占了大量cpu,googl
今天写这个是为了 提醒自己 编程过程 不仅要有逻辑 思想 还有要规范 代码 这样可读性 1、PHP 编程规范与编码习惯最主要的有以下几点: 1 文件说明 2 funct
摘要:虚拟机安装时一般都采用最小化安装,默认没有lspci工具。一台测试虚拟网卡性能的虚拟机,需要lspci工具来查看网卡的类型。本文描述了在一个虚拟机中安装lspci工具的具体步骤。 由于要测试
1、修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统
目录 算术运算符 基本四则运算符 增量赋值运算符 自增/自减运算符 关系运算符 逻
如下所示: ? 1
MapperScannerConfigurer之sqlSessionFactory注入方式讲解 首先,Mybatis中的有一段配置非常方便,省去我们去写DaoImpl(Dao层实现类)的时间,这个
Linux的网络虚拟化是LXC项目中的一个子项目,LXC包括文件系统虚拟化,进程空间虚拟化,用户虚拟化,网络虚拟化,等等,这里使用LXC的网络虚拟化来模拟多个网络环境。 本文从基本的网络设备讲
? 1
我是一名优秀的程序员,十分优秀!