乐趣区

关于java:泛型的介绍

泛型是 JDK5.0 之后推出的新个性,泛型这种语法机制,只在程序编译阶段起作用,只是给编译器参考的,运行阶段泛型是不起作用的。

应用泛型的益处


1) 汇合中存储的元素类型对立了。2)汇合中取出来的元素类型是泛型指定的类型,不须要进行大量的“向下转型”。

泛型的毛病

 
1)汇合存储的元素短少多样性。大多数业务中,汇合中的元素类型还是对立的,所以这种性能还是被大家认可的。

案例

首先创立一个 JAVA 我的项目,在我的项目中创立一个类,类外面写上主办法,而后在这个类中再创立三个类,其中一个类是剩下两个类的父类。每个类里都写上一个办法,而后子类重写父类的 eat 办法。

主办法中创立一个 List 汇合先不指定泛型,用 list.add 办法将咱们创立的类的对象存入到汇合中,因为是三个不同的类所以存入到汇合中的元素类型也是不一样的,接下来咱们用调用 list 的迭代器办法来遍历汇合。

能够看到 it.next 办法返回的对象是一个 Object 类,而这个类中并没有提供 eat 办法。所以咱们调用不了编译器报错。要想解决这个办法咱们能够应用向下转型(强制转换)。

这样把 it.next 返回的类型强制转换成 Animals 类就能够调用外面的 eat 办法了,能够看到控制台输入了三个 eat 的办法,别离是三个不同类的,因为子类继承了父类而后重写了办法(不重写的话默认是父类的 eat 办法体内容),咱们之前通过 list.add 增加了三个类的对象再汇合中所以遍历输入了三个类的 eat 办法。

如果要应用泛型咱们须要再汇合上用 < 类型 > 尖括号外面写上你要指定的汇合中能存储的元素类型。
迭代器上也要写上你要指定遍历的元素类型。

这样你的 List 汇合中能存储的元素类型就是你用泛型指定的类型,
因为迭代器上用了泛型所以遍历的也是汇合外面这个泛型指定的类型,it.next 中返回的类型就是你指定的类型,咱们之所以指定 Animals 而不是指定它的子类是因为如果你指定其中一个子类那么剩下的 Animals 中的子类就不能存储到元素中编译器会报错因为不是同个类型。

应用了泛型后迭代器循环中就不须要把 Object 类强制转换成 Animals 了,因为 it.next 默认返回的类型就是你指定的类型。

如果要输入子类的特有办法咱们还是须要向下转型将 Animals 转换成它的子类,无论是不是用泛型,这样才不会编译报错,因为是特有办法,父类中并没有写这个办法,这个办法是子类特有的所以,不能应用父类对象调用子类办法,只能向下转型。

在 JDK8 之后引入了主动类型推断机制(也称为钻石表达式)

也就是 ArrayList 前面的尖括号里能够不写类型了,它会主动推断,只有在 JDK8 之后才容许。因为这两个尖括号看起来像钻石所以也叫钻石表达式。

自定义泛型

自定义泛型的应用办法,创立一个类。类名前面写上泛型,这个泛型里的内容是个标识符能够轻易写,个别写 E(Element)和 T(Type)。而后写上泛型后,类里的办法如果有参数就必须是这个类上的泛型的标识符,也能够没有参数,如果有返回类型的话也必须是这个泛型的标识符,也能够是 void。

能够看到当咱们在办法里 new 对象时如果加上泛型那么这个泛型就会传到咱们在类上写的泛型,就会传到办法的类型参数或者返回类型上,这样就是自定义泛型。在创立 GenericaTest 对象时在写上泛型 String 这样传到类中,就会把 E 改成 String,办法里的参数 E o 也就变成 String o 办法返回值上的 public E run() 就变成 public String run()。在调用这两个办法,add()中须要传入一个 String 类型参数否则会报错,而 run() 办法返回值则能够是 String 或者 Object 因为 Object 是所有没有被动继承类的超级父类。

退出移动版