博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA 泛型理解
阅读量:7089 次
发布时间:2019-06-28

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

一直对java泛型一知半解,决定好好理解一下泛型.


##泛型的基本使用: 我们最常用到泛型的地方可能是arraylist中,如:ArrayList<Integer> intList = new ArrayList<Integer>();它可以构造各种类型的变量来组装成不同的list而不必对每一个类型都创建一个Arraylist的类,

  • 定义及使用:
//定义class Person
{
// 此处可以随便写标识符号       private T x ;            private T y ;            public void setAge(T x){
//作为参数          this.x = x ;      }      public void setName(T y){          this.y = y ;      }      public T getAge(){
//作为返回值          return this.x ;      }      public T getName(){          return this.y ;      }  };复制代码

因为T表示派生自Object类的任何类,所以尖括号T中必须是继承自Object,如:String,Interger,不能使用原始的类型,如int,double.

//使用//设置年龄 Person
 p = new Person
() ;   p.setAge(new Integer(100)) ;   System.out.println(p.getAge());   复制代码
//设置名字  Person
 p = new Person
() ;   p.setName(new String("name")) ;   System.out.println(p.getName()); 复制代码

###使用的Class object来传递类的class对象 我们在解析Json的时候:

public static List
parseSuccessArray(String response){ List
modelList = JSON.parseArray(response, SuccessModel.class); return modelList; } 复制代码

这样做比较的死板,我们可以吧successmodel抽取出来,当做一个变量,这样就可以使用到泛型了,如下:

public static 
List
parseArray(String response,Class
object){ List
modelList = JSON.parseArray(response, object); return modelList; } 复制代码

注意到,我们用的Class object来传递类的class对象,即我们上面提到的SuccessModel.class,这样就可以传递任意的class来解析不同的数据.

//待续。。。。 ##进阶 ###类型绑定: 有时候定义泛型的时候可能希望泛型类型只能是一部分类型,就是给泛型指定一个界限, 定义形式为:

复制代码

T和BoundingType可以是类,也可以是接口。另外注意的是,此处的”extends“表示的子类型,不等同于继承。在这里extends后的BoundingType可以是类,也可以是接口. ###通配符: 通配符用?表示无边界通配符,通配符的意义就是他是一个未知的符号,可以表示任意的类,如:

Point
point; point = new Point
(3,3); point = new Point
(4.3f,4.3f); point = new Point
(4.3d,4.90d); point = new Point
(12l,23l); 复制代码
  • 通配符?和T的区别: 泛型变量T不能在代码用于创建变量,只能在类,接口,函数中声明以后,才能使用。 而无边界通配符?则只能用于填充泛型变量T,表示通配任何类型 如:
Box
box; box = new Box
(); 复制代码

?只能出现在Box<?> box;中,其它位置都是不对的

  • 通配符?的extends绑定: 通配符可以和泛型一样加以限定。如:
Point
point;复制代码

注意:利用<? extends Number>定义的变量,只可取其中的值,不可修改 如:

Point
point = new Point
(3);复制代码

point的类型是由Point<? extends Number>决定的,并不会因为point = new Point(3);而改变类型。如果会改变类型那么<? extends Number>就失去了作用。但取值时,正由于泛型变量T被填充为<? extends Number>,所以编译器能确定的是T肯定是Number的子类,编译器就会用Number来填充T。 ###通配符?的super绑定: 如果说 <? extends XXX>指填充为派生于XXX的任意子类的话,那么<? super XXX>则表示填充为任意XXX的父类. 如:

class CEO extends Manager {  }    class Manager extends Employee {  }    class Employee {  }  List
list; list = new ArrayList
();list = new ArrayList
();list = new ArrayList
();//编译会报错复制代码

因为CEO类已经不再是Manager的父类了。所以会报编译错误。 注意:super通配符表示的实例内容:能存不能取 先看存的部分:

List
list; list = new ArrayList
(); //存 list.add(new Employee()); //编译错误 list.add(new Manager()); list.add(new CEO()); 复制代码

为什么会报编译错误呢?因为 编译器无法确定<? super Manager>的具体类型,但唯一可以确定的是Manager()、CEO()肯定是<? super Manager>的子类,所以肯定是可以add进去的。但Employee不一定是<? super Manager>的子类,所以不能确定,不能确定的,肯定是不允许的,所以会报编译错误。 super和extends相反,使用super关键字时,往里存的只要是Employee的子类,就会强制转换为Employee存储,但是取出来时应该都为父类Employee所以没有意义,所以我们认为super通配符:能存不能取; ##总结 extends 和 the ? super 通配符的特征,我们可以得出以下结论: ◆ 如果你想从一个数据类型里获取数据,使用 ? extends 通配符(能取不能存) ◆ 如果你想把对象写入一个里,使用 ? super 通配符(能存不能取) ◆ 如果你既想存,又想取,那就别用通配符。

参考链接:  

转载于:https://juejin.im/post/5a3396cd6fb9a045186acb46

你可能感兴趣的文章
php框架-hoby
查看>>
7.1 vim编辑器
查看>>
bash 词频统计
查看>>
Python之转义字符表
查看>>
mysql并发插入重复数据问题的解决思路
查看>>
MySQL 5.7.x修改root默认密码(CentOS下)
查看>>
Linux下动态加载SO文件
查看>>
Mysql创建、删除用户
查看>>
我的友情链接
查看>>
MySQL-MySQL常用命令
查看>>
Linux iptraf 网络监控
查看>>
Swift::8::枚举
查看>>
ZABBIX web端 显示 server 运行状态 不
查看>>
Aspose.Words使用教程之在文档中找到并替换文本
查看>>
ORACLE官方文档如何学习
查看>>
google guava包集合类HashMultiset的基本用法
查看>>
linux 进程和线程
查看>>
网工考试!
查看>>
Spring Boot 项目脚本(启动、停止、重启、状态)
查看>>
专访路彦雄:理解语言其实还是很难的
查看>>