意味:
你可以在一个类/方法/接口/实现类的头部,以’’ / ‘’ / ‘’ / ''等字母,将其泛型定义为一个其调用处所传递过来的泛型,这样一来,‘类/方法/接口/实现类’就变得更灵活化了.
而这个字母,统称为"自定义泛型字母"或"自定义泛型标识符".
可以自由地对某个类/方法/接口/实现类传递你想传递的参数类型,比如你有时要传递String类型,有时要传递Integer类型,有时又要传递对象类之类型,那么就需要定义’自定义泛型’了
注意:当定义多个自定义泛型时,都在一个尖括号’<>'内定义,但是其标识符字母不能相同.如:<E,T> √ <E,E> ×
1.类的泛型自定义与调用
一/声明格式:
1/单个泛型类格式:
类的权限修饰符 class 类名 <自定义泛型字母>{
}
列如:
public class ClassType <E>{
}
2/多个泛型类格式:
类的权限修饰符 class 类名 <自定义泛型字母A,自定义泛型字母B>{
}
列如:
public class ClassType <E,T>{
}
2/变量格式:
变量的权限修饰符 <自定义类型字母> 变量名;
列如:
private E name;
注意:自定义类型字母 要同类的一致.
二/调用:
1/单个泛型类调用格式:
类名<泛型> 自定义对象名 = new 类名<>();
如:ClassType<String> stringType = new ClassType<>();
2/多个泛型类调用格式:
类名<泛型A,泛型B> 自定义对象名 = new 类名<>();
如:ClassType<String,Integer> stringType = new ClassType<>();
2. 方法的泛型自定义与调用
一/声明格式:
1/单个方法泛型声明格式:
方法的权限修饰符 <自定义类型字母> 返回值类型 方法名(自定义类型字母 形参名称){
//方法体;
}
列如:
public <T> void typeMethod(T typeParam){
System.out.println("成功访问自定义泛型方法!,其数据为:"+typeParam);
}
2/多个个方法泛型声明格式:
方法的权限修饰符 <自定义类型字母A,自定义泛型字母B> 返回值类型 方法名(自定义类型字母A 形参名称,自定义泛型字母B 形参名称){
//方法体;
}
列如:
public <T,C> void typeMethod(T typeParamT,C typeParamC){
System.out.println("成功访问自定义泛型方法!,其数据为:"+typeParamT);
System.out.println("成功访问自定义泛型方法!,其数据为:"+typeParamC);
}
二/调用
1/单个泛型方法调用格式:
对象名/类名.方法名(实参);
列如:
integerType.typeMethod("啊啊啊啊");
2/多个泛型方法调用格式:
对象名/类名.方法名(实参A,实参B)
列如:
integerType.typeMethod("啊啊啊啊",12121);
注意:1/如果方法所在的类也有泛型标识符,那么方法其中的泛型标识符字母不能和类的泛型标识存在冲突.
因此假如在类的泛型标识符为’E’的情况下,方法的类型标识符则为’T’等等.
2/左侧泛型标识符和右侧泛型标识符要一致.
3. 接口的泛型自定义与调用
一/接口泛型声明格式:
1/单个接口泛型声明格式:
接口的权限修饰符 interface 接口名<自定义泛型字母>{
}
列如:
public interface InterfaceType<T> {
}
2/多个接口泛型声明格式:
接口的权限修饰符 interface 接口名<自定义泛型字母A,自定义泛型字母B>{
}
列如:
public interface InterfaceType<T,E> {
}
二/调用
1/单个接口泛型调用格式(以匿名对象的内部匿名实现类举例):
接口名<泛型> 自定义对象名 = new 接口名<泛型>(){
//重写体
};
列如:
InterfaceType<String> a = new InterfaceType<String>() {
@Override
public void interfaceTypeOfPost() {
System.out.println("你好");
}
};
1/多个接口泛型调用格式(以匿名对象的内部匿名实现类举例):
接口名<泛型A,泛型B> 自定义对象名 = new 接口名<泛型A,泛型B>(){
//重写体
};
列如:
InterfaceType<String,Integer> a = new InterfaceType<String,Integer>() {
@Override
public void interfaceTypeOfPost() {
System.out.println("你好");
}
};
4. 实现类的泛型自定义与调用
一/实现类泛型声明格式:
1/单个实现类泛型声明格式:
权限修饰符 class 实现类名称<自定义泛型字母> implements 接口<自定义泛型字母>{
//实现体
}
列如:
public class interfaceTypeOfUse<T> implements InterfaceType<T>{
@Override
public void interfaceTypeOfPost() {
}
2/多个实现类泛型声明格式:
权限修饰符 class 实现类名称<自定义泛型字母> implements 接口<自定义泛型字母A,自定义泛型字母B>{
//实现体
}
列如:
public class interfaceTypeOfUse<T,B> implements InterfaceType<T,B>{
@Override
public void interfaceTypeOfPost() {
}
二/调用
1/单个实现类泛型声明格式 :
实现类名称<泛型> 自定义对象名 = new 实现类名称<>();
interfaceTypeOfUse<String> stringinterfaceTypeOfUseObj = new interfaceTypeOfUse<>();
2/多个实现类泛型声明格式
实现类名称<泛型A,泛型B,> 自定义对象名 = new 实现类名称<>();
interfaceTypeOfUse<String,Integer> stringinterfaceTypeOfUseObj = new interfaceTypeOfUse<>();
注意:
1/头部左侧的泛型标识符要与右侧泛型标识符一致.
2/实现类的标识符与接口的标识符可以不一致.但是标识符数量要一致,假如接口有多个泛型标识符,那么实现类也有相等.
如:接口的<T,B>对应实现类的<E,A>√ 而不是:接口的<A,B,T>对应实现类的<A,B>×
5. 限定其类/方法/接口/实现类之泛型的范围
意义:如果想指定其使用的泛型在特定范围,如只能让其泛型用于String,Integer,Byte这三个类型,那么就需要限定.
规则:
1/限定类型上限
右侧尖括号’<>‘泛型,只能填写相对于左侧尖括号’<>'类名继承层级,相等或[以下]的类型.
格式:类名<?extends 被指定的类名> 自定义对象名 = new 类名<较左侧类名的继承层级相等或以下的泛型类型>();
列如:List<?enxtends Number> numberSetUp = new Arraylist();
含义:Number的父类有Object,子类有Integer,在限定上限了的情况下,右侧泛型不能用Object类型,只能用其子类Integer类型或其相等的Number类型.
2/限定类型下限
右侧尖括号’<>‘泛型,只能填写相对于左侧尖括号’<>'类名继承层级,相等或[以上]的类型.
格式:类名<?extends 被指定的类名> 自定义对象名 = new 类名<较左侧类名的继承层级相等或以上的泛型类型>();
列如:List<?enxtends Number> numberSetUp = new Arraylist<Object();
含义:Number的父类有Object,子类有Integer,在限定下限了的情况下,右侧泛型不能用Integer类型,只能用其父类Object类型或其相等的Number类型.
实例:
主方法(包括泛型方法/匿名实现类):FanXing.java
泛型接口:InterfaceType.java
泛型类:ClassType.java
实现类:InterfaceTypeOfUse.java
1.主方法(包括泛型方法/匿名实现类):FanXing.java
public class FanXingClass {
public static void main(String[] args) {
//定义类的泛型之 自定义为String
ClassType<String> stringType = new ClassType<>("你好","世界","2000");
//定义类的泛型之 自定义为Integer
ClassType<Integer> integerType = new ClassType<>(121,121,1212);
//调用单个泛型的方法
integerType.typeMethod("啊啊啊啊");
//调用多个泛型的方法
integerType.typeMethod("啊啊啊啊",12121);
//匿名实现自定义泛型接口
InterfaceType<String> a = new InterfaceType<String>() {
@Override
public void interfaceTypeOfPost() {
System.out.println("你好");
}
};
//实现类之泛型 限定上线
List<?extends Number> upSet = new ArrayList<Number>();
}
}
2.泛型接口:InterfaceType.java
public interface InterfaceType<B> {
void interfaceTypeOfPost();
}
3.泛型类:ClassType.java
package code.study.FanXing;
public class ClassType<E> {
private E name;
private E Address;
private E Birthday;
//单个泛型形参
public <T> void typeMethod(T typeParam){ //如果方法所在的类也有泛型标识符,那么方法其中的泛型标识符字母不能和类的泛型标识存在冲突.
//因此在类的泛型标识符为'E'的情况下,方法的类型标识符为'T'.
System.out.println("成功访问自定义泛型方法!,其数据为:"+typeParam);
}
//多个泛型形参
public <T,B> void typeMethod(T typeParam,B typeParamB){
System.out.println("成功访问自定义泛型方法!,其数据为:"+typeParam);
System.out.println("成功访问自定义泛型方法!,其数据为:"+typeParamB);
}
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
public E getAddress() {
return Address;
}
public void setAddress(E address) {
Address = address;
}
public E getBirthday() {
return Birthday;
}
public void setBirthday(E birthday) {
Birthday = birthday;
}
public ClassType() {
}
public ClassType(E name, E address, E birthday) {
this.name = name;
Address = address;
Birthday = birthday;
}
}
4.实现类:InterfaceTypeOfUse.java
public class interfaceTypeOfUse<T> implements InterfaceType<T>{
@Override
public void interfaceTypeOfPost() {
System.out.println("你好,我是泛型接口的实现类");
}
}