博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
泛型-通配符,受限泛型(上限和下限)
阅读量:5062 次
发布时间:2019-06-12

本文共 5931 字,大约阅读时间需要 19 分钟。

掌握通配符“?”的使用。

掌握受限泛型的设置。

掌握泛型与子类继承的限制。

具体内容

1.1匹配任意类型的通配符

  在开发中对象的引用传递(向上向下传递)是最常见的,但是,在泛型的操作中,在进行引用传递的时候泛型类型必须匹配才可以传递,否则不能传递。

  例如,如下没有进行泛型类型匹配,一个是String,一个是Object类型。

package Thread1;class Info
{ private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class demo1{ public static void main(String args[]){ Info
i = new Info
() ; // 使用String为泛型类型 i.setVar("MLDN") ; // 设置内容 fun(i) ;                    //把String泛型类型的i对象传递给Object泛型类型的temp。 } public static void fun(Info
temp){ // 接收Object泛型类型的Info对象 System.out.println("内容:" + temp) ; }};

  编译发生错误。

Exception in thread "main" java.lang.Error: Unresolved compilation problem:     The method fun(Info) in the type demo1 is not applicable for the arguments (Info
) at Thread1.demo1.main(demo1.java:18)

  泛型对象进行引用传递的时候,类型必须一致,如果非要传递,则可以将fun方法中Info参数的泛型取消掉(变成 void fun(Info temp)。、

  以上确实改进了功能,但是似乎不是很妥当,毕竟之前指定过泛型。

  以上程序在fun()方法中使用"Info<?>"的代码形式,表示可以使用任意的泛型类型对象,这样的话fun()方法定义就合理了,但是使用以上方法也有需要注意的地方,

即:如果使用“?“接收泛型对象的时候,则不能设置被泛型指定的内容

class Info
{ private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class GenericsDemo14{ public static void main(String args[]){ Info
i = new Info
() ; // 使用String为泛型类型 i.setVar("MLDN") ; // 设置内容 fun(i) ; } public static void fun(Info
temp){ // 可以接收任意的泛型对象 System.out.println("内容:" + temp) ; }};

  如果使用”?“意味着可以接收任意的内容,但是此内容无法直接使得用”?“修饰的泛型的对象进行修改。如下就会出问题:

package Thread1;class Info
{ private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class demo1{ public static void main(String args[]){ Info
i = new Info
() ; // 使用String为泛型类型 i.setVar("MLDN") ; // 设置内容,这里会出错,因为”?“通配符修饰的对象只能接收,不能修改,也就是不能设置。 }};

  运行结果:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:     The method setVar(capture#1-of ?) in the type Info
is not applicable for the arguments (String) at Thread1.demo1.main(demo1.java:17)

  在使用”?“只能接收,不能修改。

1.2受限泛型

  之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。

  

设置上限

class Info
{ private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class GenericsDemo17{ public static void main(String args[]){ Info
i1 = new Info
() ; // 声明Integer的泛型对象 Info
i2 = new Info
() ; // 声明Float的泛型对象 i1.setVar(30) ; // 设置整数,自动装箱 i2.setVar(30.1f) ; // 设置小数,自动装箱 fun(i1) ; fun(i2) ; } public static void fun(Info
temp){ // 只能接收Number及其Number的子类 System.out.print(temp + "、") ; }};

  运行成功。但是,如果传人的泛型类型为String的话就不行,因为String不是Number子类。

  在类中使用泛型上限。

package Thread1;class Info
{ // 此处泛型只能是数字类型 private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class demo1{ public static void main(String args[]){ Info
i1 = new Info
() ; // 声明Integer的泛型对象 }};

  如果在使用Info的时候设置成String类型,则编译的时候将会出现错误(String不是Number子类):

设置下限

  

class Info
{ private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class GenericsDemo21{ public static void main(String args[]){ Info
i1 = new Info
() ; // 声明String的泛型对象 Info
i2 = new Info() ; // 声明Object的泛型对象 i1.setVar("hello") ; i2.setVar(new Object()) ; fun(i1) ; fun(i2) ; } public static void fun(Info
temp){ // 只能接收String或Object类型的泛型,String类的父类只有Object类 System.out.print(temp + "、") ; }};

  Object类和String类都是String的父类,所有运行成功,但是如果此时用Integer则会出错,因为integer并不是String父类。

1.3解释:泛型与子类继承的限制。

  一个类的子类可以通过对象多态性,为其父类实例化,但是在泛型操作中,子类的泛型类型是无法使用父类的泛型类型接收的。例如:Info<String>不能使用Info<Object>

接收。

  例如,以下肯定出错。

class Info
{ private T var ; // 定义泛型变量 public void setVar(T var){ this.var = var ; } public T getVar(){ return this.var ; } public String toString(){ // 直接打印 return this.var.toString() ; }};public class GenericsDemo23{ public static void main(String args[]){ Info
i1 = new Info
() ; // 泛型类型为String Info
i2 = null ; i2 = i1 ;                  //这里因为对象泛型类型不同,而出错。 }};

  Object肯定比String大。

总结

  1)使用?可以接收任意泛型对象。

  2)泛型的上限:?extends 类型。

  3)泛型的下限:?super 类型。相对了解一些就可。

  4)了解为什么泛型子类之间的继承无法直接转换的原因。

转载于:https://www.cnblogs.com/alsf/p/5690052.html

你可能感兴趣的文章
Java实体书写规范
查看>>
App右上角数字
查看>>
从.NET中委托写法的演变谈开去(上):委托与匿名方法
查看>>
六、PowerDesigner 正向工程 和 逆向工程 说明
查看>>
小算法
查看>>
201521123024 《java程序设计》 第12周学习总结
查看>>
贪吃蛇游戏改进
查看>>
新作《ASP.NET MVC 5框架揭秘》正式出版
查看>>
“前.NET Core时代”如何实现跨平台代码重用 ——源文件重用
查看>>
【POJ1845】Sumdiv(数论/约数和定理/等比数列二分求和)
查看>>
在WPF中使用Caliburn.Micro搭建MEF插件化开发框架
查看>>
IdentityServer4-用EF配置Client(一)
查看>>
UWP: 掌握编译型绑定 x:Bind
查看>>
asp.net core系列 35 EF保存数据(2) -- EF系列结束
查看>>
WPF程序加入3D模型
查看>>
WPF中实现多选ComboBox控件
查看>>
读构建之法第四章第十七章有感
查看>>
C#中的IEnumerable<T>知识点
查看>>
android访问链接时候报java.net.MalformedURLException: Protocol not found
查看>>
dwz ie10一直提示数据加载中
查看>>