Java开发——23.泛型

简介: 泛型的通配符/定义格式。

我们查看API帮助文档可知,Collection接口的定义格式为Interface Collection<E>,那么<E>代表什么呢?E - 此集合中元素的类型 !为什么要用<>括起来呢?就是我们将要学习到的泛型。


学习思路:

image.png


泛型的通配符:

泛型中的通配符有四种:T、E、K V、?


泛型有以上四种定义格式;

T Java的类型的是一个形参!在方法声明的时候使用。一般指代泛型类


E  通常用于规定集合中的元素类型。


K V  般表示Java中Map集合的键值对。


一般表示不确定的Java类型,这是一种无限的符号,代表任何类型都可以。是一个实参!在方法使用的时候直接调用,但是 ?不能作为元素类型添加值,也就是 ?只能在没有定义元素类型的时候接收不同类型的元素。

?一般只是接收某种数据类型,并不能作为返回值;

?extends XX:向下限定,E及其子类;

? super XX:向上限定,E极其父类。

(在后面详细讲解 ?请继续学习。)


在学习Collection集合的时候,我们了解到,集合可以存储任意类型的元素,那么我们如果在使用增强for循环遍历集合的过程中,不使用Object接收对象,而使用特定的元素类型,就会爆出ClassCastException异常,表示类型转换异常,类型不兼容


publicstaticvoidmain(String[] args) {
//此处指定了Collection集合的类型为Integer,所以不能添加别的元素类型Collection<Integer>num=newArrayList();
num.add(123);
num.add(456);
num.add(789);
// num.add("123");在编译的时候都会报错//我们定义了一个没有指定类型的Collection集合Collectionstr=newArrayList();
str.add("123");
str.add("456");
str.add("789");
//因为指定集合的元素类型<E>,只会在编译的时期判断,存入的内容类型//在运行时会把元素类型都默认为Object类型,这就叫做“泛型的擦除”num.addAll(str);
//在增强for循环的时候我们使用了Integer作为元素输出类型//但是num集合中是存在String类型的元素的,所以会存在类型不兼容无法完成遍历for (Integerin : num){
System.out.println(in);
        }
}

image.png



泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。


泛型类:

<数据类型> 此处的数据类型只能是引用类型

好处:

A:把运行时期的问题提前到了编译期间 ;

B:避免了强制类型转换。


/** 泛型类:把泛型定义在类上*/publicclassObjectTool<T> {
privateTobj;
publicTgetObj() {
returnobj;
    }
publicvoidsetObj(Tobj) {
this.obj=obj;
    }
}


/** 泛型类的测试*/publicclassObjectToolDemo {
publicstaticvoidmain(String[] args) {
ObjectTool<String>ot=newObjectTool<String>();//规范了数据的存储ot.setObj(newString("江一燕"));
Strings=ot.getObj();
System.out.println("姓名是:"+s);
ObjectTool<Integer>ot2=newObjectTool<Integer>();
ot2.setObj(27);
Integeri=ot2.getObj();
System.out.println("年龄是:"+i);
    }
}


泛型方法:

修饰符 <代表泛型的变量>  返回值类型  方法名 (参数){  }


//普通方法//修饰符 返回值类型 方法名(参数){}publicintshow(inti){
returni;
    }
/** 泛型方法:把泛型定义在方法上*/public<T>Objectshow(Tt) {
returnt;
    }
//定义一个泛型方法//返回类型不应该明确,因为泛型方法的类型都不明确//建议:Object 或者  T(泛型)public<T>Tshow(Tt){
returnt;
    }



//实现类publicclassTestCollection {
public<T>Objectshow(Tt){
returnt;
    }
public<T>Tshow2(Tt){
returnt;
    }
publicintshow(inti){
returni;
    }
publicstaticvoidmain(String[] args) {
System.out.println(newTestCollection().show(1111111111));
System.out.println(newTestCollection().show("2222222222"));
System.out.println(newTestCollection().show2(newDate()));
    }
}
/*11111111112222222222Tue May 03 16:03:35 CST 2022*/


泛型接口:

修饰符 interface 接口名<代表泛型的变量> {  }


/** 泛型接口:把泛型定义在接口上*/publicinterfaceInter<T> {
publicabstractvoidshow(Tt);
}



//实现类在实现接口的时候//第一种情况:已经知道该是什么类型的了publicclassInterImplimplementsInter<String> {
@Overridepublicvoidshow(Stringt) {
System.out.println(t);
  }
}
//第二种情况:还不知道是什么类型的publicclassInterImpl<T>implementsInter<T> {
@Overridepublicvoidshow(Tt) {
System.out.println(t);
  }
}


//测试类publicstaticvoidmain(String[] args) {
//第一种情况:实现类已经明确类型,实例化对象时必须与实现类中的类型一致InterDemo<String>i=newInteImpl();//我在实现的时候,已经明确类型--Stringi.show("aaa");
i.show("bbb");
//第二种情况:实现类也没有明确类型InterDemo<Integer>ii=newInteImpl2<>();//我在实现的时间也没有给出明确ii.show(11);
ii.show(22);
InterDemo<String>ii2=newInteImpl2<>();//我在实现的时间也没有给出明确ii2.show("11");
ii2.show("22");
    }
}


当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。


关于 ?通配符:

泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接受数据,不能往该集合中存储数据



/** 泛型高级(通配符)* ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了* ? extends E:向下限定,E及其子类* ? super E:向上限定,E极其父类*/publicclassAnimal {
}
publicclassDogextendsAnimal {
}
publicclassCatextendsAnimal {
}
publicclassGenericDemo {
publicstaticvoidmain(String[] args) {
// 泛型如果明确的写的时候,前后必须一致Collection<Object>c1=newArrayList<Object>();
//错误写法:// Collection<Object> c2 = new ArrayList<Animal>();// Collection<Object> c3 = new ArrayList<Dog>();// Collection<Object> c4 = new ArrayList<Cat>();// ?表示任意的类型都是可以的Collection<?>c5=newArrayList<Object>();
Collection<?>c6=newArrayList<Animal>();
Collection<?>c7=newArrayList<Dog>();
Collection<?>c8=newArrayList<Cat>();
// ? extends E:向下限定,E及其子类,表示包括E在内的任何子类;// Collection<? extends Animal> c9 = new ArrayList<Object>();Collection<?extendsAnimal>c10=newArrayList<Animal>();
Collection<?extendsAnimal>c11=newArrayList<Dog>();
Collection<?extendsAnimal>c12=newArrayList<Cat>();
// ? super E:向上限定,E极其父类,表示包括E在内的任何父类;Collection<?superAnimal>c13=newArrayList<Object>();
Collection<?superAnimal>c14=newArrayList<Animal>();
// Collection<? super Animal> c15 = new ArrayList<Dog>();// Collection<? super Animal> c16 = new ArrayList<Cat>();  }
}


相关文章
|
1天前
|
Java 数据安全/隐私保护 Spring
Java 中 Spring Boot 框架下的 Email 开发
Java 中 Spring Boot 框架下的 Email 开发
18 2
|
1天前
|
安全 Java 编译器
java泛型浅谈
java泛型浅谈
6 1
|
1天前
|
存储 安全 Java
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
|
1天前
|
存储 Java 数据库连接
使用Java开发桌面应用程序
使用Java开发桌面应用程序
20 0
|
1天前
|
Java API 开发工具
java与Android开发入门指南
java与Android开发入门指南
15 0
|
1天前
|
分布式计算 负载均衡 Java
构建高可用性Java应用:介绍分布式系统设计与开发
构建高可用性Java应用:介绍分布式系统设计与开发
13 0
|
1天前
|
前端开发 安全 Java
使用Spring框架加速Java开发
使用Spring框架加速Java开发
56 0
|
1天前
|
前端开发 JavaScript Java
Java与Web开发的结合:JSP与Servlet
Java与Web开发的结合:JSP与Servlet
12 0
|
1天前
|
设计模式 算法 Java
设计模式在Java开发中的应用
设计模式在Java开发中的应用
18 0
|
1天前
|
监控 Java Maven
揭秘Java Agent技术:解锁Java工具开发的新境界
作为JDK提供的关键机制,Java Agent技术不仅为Java工具的开发者提供了一个强大的框架,还为性能监控、故障诊断和动态代码修改等领域带来了革命性的变革。本文旨在全面解析Java Agent技术的应用场景以及实现方式,特别是静态加载模式和动态加载模式这两种关键模式。
45 0