Java基础之泛型程序设计
2023-04-18 14:57:24 时间
Java基础之泛型程序设计
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说Java基础之泛型程序设计,希望能够帮助大家进步!!!
泛型程序设计
简要介绍
- 类型变量使用大写形式,且比较短,在Java库中,使用变量E表示集合的元素类型,K和V分别表示表的关键字与值得类型。Object 表示”任意类型”
- 程序清单使用了Pair类,静态的minmax方法遍历了数组并同时计算出最大值和最小值。它用一个Pair对象返回了两个结果。
compareTo
方法只有Comparable
接口有该方法,所以我们要将T限制为实现了Comparable
接口的 的类
类型擦除
无论何时定义一个泛型类型,都自动提供了一个相应的原始类型,原始类型的名字就是删去参数后的泛型类型名,擦除类型变量,并替换为限定类型(无限定的变量用Object) 例如:Pair 的原始类型如下所示:
public class Pair <Object>{
private Object name;
private Object bonus;
public Object getFirst() {
return name;
}
public void setFirst(Object name) {
this.name = name;
}
public Object getSecond() {
return bonus;
}
public void setSecond(Object bonus) {
this.bonus = bonus;
}
public Pair(){}
public Pair(Object name, Object bonus) {
this.name = name;
this.bonus = bonus;
}
@Override
public String toString() {
return "Pair{" +
"name=" + name +
", bonus=" + bonus +
'}';
}
类型擦除带来的方法参数不统一,编译器通过桥方法来处理。
与Java泛型转换的事实
- 虚拟机中没有泛型,只有普通的类和方法。
- 所有的类型参数都用它们的限定类型替换
- 桥方法被合成来保持多态
- 为保持类型安全性,必要时插入强制类型转换。
约束与局限性
- 不能用基本类型实例化类型参数
例如没有 Pair<double>
,只有 Pair<Double>
- 运行时类型查询只适用于原始类型 例如:
Pair<String> stringPair=new Pair<String>();
Pair<Employee> employeePair=new Pair<Employee>();
if(stringPair.getClass()==employeePair.getClass())
其比较结果是true,这是因为两次调用getClass都将返回 Pair.class
- 不能创建参数化类型的数组
例如:
Pair<String>[] table=new Pair<String>[10]
//error - Varargs 警告
public static <T> void addAll(Collection<T> coll,T ... ts){
for(t: ts) coll.add(t);
}
现考虑以下调用:
Collection<Pair<String>> table=...;
Pair<String> pair1=...;
Pair<String> pair2=...;
Pair<String> pair3=...;
addAll(table,pair1,pair2);
为了调用这个方法,Java虚拟机必须建立一个Pair 数组。这就违反了前面的规则。 不过,对于这种情况,规则有所放松,你只会得到一个警告,而不是错误。
可以采取两种方法来抑制这个警告。一种方法是为包含addAll调用的方法增加注解@SuppressWarnings(“unchecked”)。或者在Java SE 7中,还 可以用@SafeVarargs直接标注addAll方法。
5 不能实例化类型变量 不能使用像new T(…),new T[…] 或T.class 这样的表达式中的类型变量,例如下面 Pair 构造器就是非法的:
public Pair(){name=new T();bonus=new T();}
类型擦除将T改变成了Object,而且,其本意肯定不希望调用new Object()。在Java SE 8之后,最好的解决办法是让调用者 提供一个构造器表达式。例如:
Pair<String> p=Pair.makePair(String::new)
6. 不能构造泛型数组 例如:
public static <T extends Comparable> T[] minmax(T[] a){T[] mm=new T[2];} //error
7. 泛型类的静态上下文中类型变量无效 不能再静态域或方法中引用类型变量。例如:
“`
public class Signleton {
private static T signleStance; //Error
public static T getSignleStance(){ //True
if(signleStance==null){
return signleStance;
}
}
}
8. 不能抛出或者捕获泛型类的实例
既不能抛出也不能捕获泛型类对象。实际上,甚至泛型类扩展Throwable都是不合法的。
例如:以下定义就不能正常编译:
`public class Problem<T> extends Exception{
}`
9. 可以通过 `@SuppressWarnings('unchecked')` 来消除对受查异常的检查。
### 泛型类型的继承规则
1. 通配符的使用
public static void main(String[] args) {
Pair managerPair = new Pair<>();
printBuddies(managerPair);
}
public static void printBuddies(Pair<? extends Employee> employeePair) {
Employee name = employeePair.getFirst();
Employee bonus = employeePair.getSecond();
System.out.println("name:"+name+"bonus:"+bonus);
}
这种情况会编译报错
//Test 2
Pair
下面是泛型的综合应用:
package com.jay.generic;
import com.jay.generic.employee.Employee;
import com.jay.generic.employee.Manager;
/**
* 泛型综合总结应用
* Created by xiang.wei on 2018/1/21
*
* @author xiang.wei
*/
public class PairTest3 {
public static void main(String[] args) {
Manager ceo = new Manager(“xiang”, 10000);
Manager cfo = new Manager(“li”, 8000);
Pair managerPair = new Pair<>(ceo, cfo);
printBuddies(managerPair);
ceo.setBonus(2000);
cfo.setBonus(1000);
Manager[] managers = {ceo, cfo};
minmaxBonus(managers, managerPair);
System.out.println("first:"+managerPair.getFirst().getName()+",second:"+managerPair.getSecond().getName());
maxminBonux(managers,managerPair);
System.out.println("first:"+managerPair.getFirst().getName()+",second:"+managerPair.getSecond().getName());
}
public static void printBuddies(Pair<? extends Employee> pair) {
Employee first = pair.getFirst();
Employee second = pair.getSecond();
System.out.println("first="+first.getName()+"------second="+second.getName());
}
public static void minmaxBonus(Manager[] managers, Pair<? super Manager> result) {
if (managers.length == 0) {
return;
}
Manager min = managers[0];
Manager max = managers[0];
for (int i = 0; i < managers.length; i++) {
if (min.getBonus() > managers[i].getBonus()) {
min = managers[i];
}
if (max.getBonus() < managers[i].getBonus()) {
max = managers[i];
}
}
result.setFirst(min);
result.setSecond(max);
}
public static void maxminBonux(Manager[] managers, Pair<? super Manager> result) {
if (managers.length == 0) {
return;
}
minmaxBonus(managers, result);
PairAlg.swapHelper(result);
}
}
/**
*
*/
class PairAlg {
/**
* @param pair
* @return
*/
public static boolean hasNulls(Pair
相关文章
- Jease 2.6发布 Java开源内容框架
- JVM调优总结:反思
- JVM调优总结:调优方法
- JVM调优总结:新一代的垃圾回收算法
- JVM调优总结:典型配置举例
- JVM调优总结:分代垃圾回收详述
- JVM调优总结:垃圾回收面临的问题
- JVM调优总结:基本垃圾回收算法
- JVM调优总结:一些概念
- 用Java GUI编写的画板程序
- Java的动态绑定机制
- jOOQ 2.0.2发布 Java的ORM框架
- Java中带复选框的树的实现和应用
- Java网络编程菜鸟进阶:TCP和套接字入门
- 甲骨文与谷歌专利权之争定于今年三月开审
- Java调用C/C++编写的第三方dll动态链接库
- 集成开发环境 NetBeans IDE 7.1正式版发布
- kangle 2.7.5紧急发布 防hash碰撞攻击
- 东方通技术引领模式为国产软件“争权”
- UML中关联,组合与聚合等关系的辨析