java泛型 tt_Java学习笔记(二一)——Java 泛型

【前面的话】

最近脸好干,掉皮,需要买点化妆品了。

Java泛型好好学习一下。

【定义】

一、泛型的定义主要有以下两种:

在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)

在程序编码中一些包含参数的类。其参数可以代表类或对象等等。(现在人们大多把这称作模板)

不论使用那个定义,泛型的参数在真正使用泛型时都必须作出指明。

二、使用泛型的目的:

一些强类型程序语言支持泛型,其主要目的是加强类型安全及减少类转换的次数,但一些支持泛型的程序语言只能达到部份目的。

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。

是对java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值得占位符一样。

【Java泛型的几种类型代码】

一、不使用泛型的代码

我们定义一个Person类,包含三个属性x,y,z。在我们开始定义地时候,我们也不知道这三个属性是用来干什么的,所以我们定义为Object类型。但是在使用的时候,我们分别对x,y,z赋予了int,double,String类型,所以在取出的时候,我们需要把这三个类型值进行强制转换。如下代码:

1. Person.java

1 public classPerson {2 privateObject x;3 privateObject y;4 privateObject z;5 //使用Object类型。可以转化为任何类型

6 publicObject getX() {7 returnx;8 }9 public voidsetX(Object x) {10 this.x =x;11 }12 publicObject getY() {13 returny;14 }15 public voidsetY(Object y) {16 this.y =y;17 }18 publicObject getZ() {19 returnz;20 }21 public voidsetZ(Object z) {22 this.z =z;23 }24 }

2. NoGenericTest.java

1 public classNoGenericTest {2 public static voidmain(String[]args){3 Person boy=newPerson();4 boy.setX(20);5 boy.setY(22.2);6 boy.setZ("帅哥TT");7 //这里根据设置的不同类型的值,我们需要进行强制类型转化。

8 int x=(Integer)boy.getX();9 double y=(double)boy.getY();10 String z=(String)boy.getZ();11

12 System.out.println(x);13 System.out.println(y);14 System.out.println(z);15 }16 }

3. 运行结果

1 20

2 22.2

3 帅哥TT

二、使用一个类型变量泛型的代码

我们定义一个泛型类Person,定义三个属性x,y,z,在测试类中,我们设置属性的值,并打印。

1. Person.java

1 public class Person{2 privateT x;3 privateT y;4 privateT z;5 publicT getX() {6 returnx;7 }8 public voidsetX(T x) {9 this.x =x;10 }11 publicT getY() {12 returny;13 }14 public voidsetY(T y) {15 this.y =y;16 }17 publicT getZ() {18 returnz;19 }20 public voidsetZ(T z) {21 this.z =z;22 }23 }

2. GenericTest.java

1 public classGenericTest {2 public static voidmain(String[]args){3 Person boy=newPerson();4 boy.setX(20);5 boy.setY(22.2);6 boy.setZ("帅哥TT");7 //不用进行类型转化

8 System.out.println(boy.getX());9 System.out.println(boy.getY());10 System.out.println(boy.getZ());11 }12 }

3. 运行结果

1 20

2 22.2

3 帅哥TT

三、使用两个类型变量泛型的代码

我们定义一个泛型类Person,定义两个属性x,y,使用了两种不同的类型变量,在测试类中,我们设置属性的值,并打印。

1. Person.java

1 public class Person{2 privateT1 x;3 privateT2 y;4 publicT1 getX() {5 returnx;6 }7 public voidsetX(T1 x) {8 this.x =x;9 }10 publicT2 getY() {11 returny;12 }13 public voidsetY(T2 y) {14 this.y =y;15 }16 }

2. GenericTest.java

1 public classGenerricTest {2 public static voidmain(String[] args){3 Person boy=new Person();4 boy.setX("帅哥TT");5 boy.setY(20);6 System.out.println(boy.getX());7 System.out.println(boy.getY());8 }9

10 }

3. 运行结果

1 帅哥TT2 20

四、使用泛型的继承

我们定义一个泛型类Person,定义两个属性x,y,然后定义另一个泛型类Boy,定义属性z,Boy继承Person类,在测试类中,我们设置属性的值,并打印。

1. Person.java

1 public class Person{2 privateT1 x;3 privateT2 y;4 publicT1 getX() {5 returnx;6 }7 public voidsetX(T1 x) {8 this.x =x;9 }10 publicT2 getY() {11 returny;12 }13 public voidsetY(T2 y) {14 this.y =y;15 }16 }

2. Boy

1 public class Boyextends Person{2 privateT3 z;3 publicT3 getZ() {4 returnz;5 }6 public voidsetZ(T3 z) {7 this.z =z;8 }9 }

3. GenericTest.java

1 public classGenericTest {2 public static voidmain(String[] args){3 Boy boy=new Boy();4 boy.setX("帅哥TT");5 boy.setY(20);6 boy.setZ(200000.22);7

8 System.out.println(boy.getX());9 System.out.println(boy.getY());10 System.out.println(boy.getZ());11 }12 }

4. 运行结果

1 帅哥TT2 20

3 200000.22

五、使用泛型的接口

我们定义一个泛型接口Person,定义两个方法,然后定义另一个泛型类Boy,实现泛型接口Person,定义属性x,y,z,在测试类中,我们设置属性的值,并打印。

1. Person.java

1 public interface Person{2 publicT1 getX();3 publicT2 getY();4 }

2. Boy

1 public class Boyimplements Person{2 privateT1 x;3 privateT2 y;4 privateT3 z;5 publicT1 getX() {6 returnx;7 }8 public voidsetX(T1 x) {9 this.x =x;10 }11 publicT2 getY() {12 returny;13 }14 public voidsetY(T2 y) {15 this.y =y;16 }17 publicT3 getZ() {18 returnz;19 }20 public voidsetZ(T3 z) {21 this.z =z;22 }23

24 }

3. GenericTest.java

1 public classGenericTest {2 public static voidmain(String[] args){3 Boy boy=new Boy();4 boy.setX("帅哥TT");5 boy.setY(20);6 boy.setZ(200000.22);7 System.out.println(boy.getX());8 System.out.println(boy.getY());9 System.out.println(boy.getZ());10 }11 }

4. 运行结果

1 帅哥TT2 20

3 200000.22

六、使用泛型方法

说明一下,定义泛型方法时,必须在返回值前边加一个,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值。

定义一个普通类Person,定义一个泛型方法,如下代码:

1.Person.java

1 public classPerson{2 public staticT getMiddle(T[]a){3 return a[a.length/2];4 }5 public static voidmain(String [] args){6 String[]name={"帅哥TT","帅哥TT1","帅哥TT2"};7 String middle=Person.getMiddle(name);8 System.out.println(middle);9

10 Integer[]num={20,22,25};11 Integer middle1=Person.getMiddle(num);12 System.out.println(middle1);13

14 Double[]num1={20.0,22.2,25.5};15 Double middle2=Person.getMiddle(num1);16 System.out.println(middle2);17 }18 }

2. 运行结果

1 帅哥TT12 22

3 22.2

七、类型变量的限定

如下代码,我们在方法min中定义了一个变量smallest类型为T,这说明了smallest可以是任何一个类的对象,我们在下面的代码中需要使用compareTo方法, 但是我们没有办法确定我们的T中含有CompareTo方法,所以我们需要对T进行限定,在代码中我们让T继承Comparable类。如下:

1 public staticT min(T[]a)

1. Person.java

1 public classPerson{2 public staticT min(T[]a){3 if(a==null||a.length==0){4 return null;5 }6 T smallest=a[0];7 for(int i=1;i0){9 smallest=a[i];10 }11 }12 returnsmallest;13 }14 public static voidmain(String [] args){15 Integer[]num={20,25,30,10};16 Integer middle=Person.min(num);17 System.out.println(middle);18 }19 }

2. 运行结果

1 10

【Java泛型理解】

一、类型擦除

正确理解泛型概念的首要前提是理解类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。如在代码中定义的List和List等类型,在编译之后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。

很多泛型的奇怪特性都与这个类型擦除的存在有关,包括:

泛型类并没有自己独有的Class类对象。比如并不存在List.class或是List.class,而只有List.class。

静态变量是被泛型类的所有实例所共享的。对于声明为MyClass的类,访问其中的静态变量的方法仍然是 MyClass.myStaticVar。不管是通过new MyClass还是new MyClass创建的对象,都是共享一个静态变量。

泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException和MyException的。对于JVM来说,它们都是 MyException类型的。也就无法执行与异常对应的catch语句。

二、最佳实践

在使用泛型的时候可以遵循一些基本的原则,从而避免一些常见的问题。

在代码中避免泛型类和原始类型的混用。比如List和List不应该共同使用。这样会产生一些编译器警告和潜在的运行时异常。当需要利用JDK 5之前开发的遗留代码,而不得不这么做时,也尽可能的隔离相关的代码。

在使用带通配符的泛型类的时候,需要明确通配符所代表的一组类型的概念。由于具体的类型是未知的,很多操作是不允许的。

泛型类最好不要同数组一块使用。你只能创建new List>[10]这样的数组,无法创建new List[10]这样的。这限制了数组的使用能力,而且会带来很多费解的问题。因此,当需要类似数组的功能时候,使用集合类即可。

不要忽视编译器给出的警告信息。

【参考资料】

【后面的话】

好好学习。

——TT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、转账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提供给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值