网站标签名词,wordpress图书主题,中小企业公司,10元建站1.泛型
泛型指类型参数化#xff0c; 在定义期间#xff0c;不知道调用时会使用什么类型#xff0c;就可以添加泛型形参#xff0c;在使用时传入实参固定类型即可。
泛型类#xff1a; 泛型应用在类上。 一般用在类名后#xff0c;用尖括号括起来。用大写字母作为泛型参…1.泛型
泛型指类型参数化 在定义期间不知道调用时会使用什么类型就可以添加泛型形参在使用时传入实参固定类型即可。
泛型类 泛型应用在类上。 一般用在类名后用尖括号括起来。用大写字母作为泛型参数。
我们可以通过一个实例更好的理解
public class PersonT {private T idCard;public Person(T idCard) {this.idCard idCard;}
我们首先定义了一个Person类并提供泛型T在传入成员变量时就可以使用泛型来定义成员变量的类型因为我们不知道在创建对象时会传入什么类型的对象在提供构造器时形参的类型就规定成泛型
public static void main(String[] args) {//测试创建一个Person对象,需要给泛型参数赋值具体类型PersonString P new Person(1001);PersonLong p3 new Person(1001L);//泛型参数只能使用引用类型不能能赋值八大基本数据类型//实例化过程中泛型可以只在一边给泛型参数赋值但是两边的不能省略}
在这里我们传入一个测试方法分别调用构造器创建两个不同类型的Person对象在类名后添加传入的实际类型就可以。需要注意传入的实际类型不能是基本数据类型因为他们没有面向对象的特征只能传入引用数据类型比如包装类或字符串类型
当有一个子类继承带有泛型的父类时一般需要给泛型传入实际类型
class Student extends PersonInteger {public Student(Integer idcard) {super(idcard);}
}需要注意的是在继承父类之后需要重写父类的构造方法
子类在继承带有泛型的父类时如果子类自己也添加了泛型可以把泛型传入父类
class TeacherE extends PersonE {public Teacher(E idcard) {super(idcard);}
}
需要注意的是子类在继承父类后需要把自己的泛型赋值给父类
如果子类不传入实际类型也不使用泛型那么子类默认使用Object泛型
class President extends Person {public President(Object idcard) {super(idcard);}
}
2.泛型接口
如果泛型应用在接口上就成为泛型接口
public interface MyComparableT, M {}
在定义泛型接口时也可以使用泛型这个比较接口就传入了两个泛型
class Employee implements MyComparableEmployee, Employee, ComparatorEmployee {String name;int age;public Employee(String name, int age) {this.name name;this.age age;}public String toString() {return [ name : age ];}//在我们自己定义的方法中实现比较规则Overridepublic int mycompare(Employee o1, Employee o2) {return o1.age - o2.age;}public int compare(Employee o1, Employee o2) {return mycompare(o1, o2);}
}
我们定义了一个类来实现两个接口一个是自定义的比较接口一个是比较器接口传入的类型都是定义的Employee类型之后定义了两个成员变量年龄和姓名提供了全参构造器并重写了toString方法并在我们自己定义的方法中确定比较原则按照年龄升序然后重写compare方法返回值就是我们自己定义的方法传入o1o2.
public static void main(String[] args) {Employee[] employees new Employee[3];employees[0] new Employee(小张, 18);employees[1] new Employee(小王, 17);employees[2] new Employee(小李, 19);
//使用比较器接口来重新定义比较规则从泛型的角度来说在实例化泛型接口时要给泛型参数传具体类型Comparator c new ComparatorEmployee() {//重写比较器里的compare方法public int compare(Employee o1, Employee o2) {//调用了自定义的员工类里的比较方法return o1.mycompare(o1, o2);}};Arrays.sort(employees, c);System.out.println(Arrays.toString(employees));}
在main方法里我们首先建立了Employee类型的数组并传入了三个值之后再在使用比较器接口新建一个比较器对象需要使用匿名内部类的方式重写compare方法调用主类中自己定义的比较规则方法就可以了之后对数组进行排序传入数组和比较器对象然后对其打印 3.泛型方法
泛型可以应用在方法上位置位于返回值类型的前面
public static T boolean equals(T t1,T t2){return t1.equals(t2);}
首先定义一个泛型方法在boolean前面添加泛型形参也是泛型对象返回对象调用equals的结果
class Cat{String name;public Cat(String name){this.name name;}Overridepublic boolean equals(Object o) {if (this o) return true;if (o null || getClass() ! o.getClass()) return false;Cat cat (Cat) o;return Objects.equals(name, cat.name);}Overridepublic int hashCode() {return Objects.hashCode(name);}
}
我们在主类Cat中需要重写equals和hashCode方法可以直接生成也可以自己撸代码
public static void main(String[] args) {Cat c1 new Cat(小黄);Cat c2 new Cat(小黄);//泛型方法在调用期间不需要传入具体类型只需要传入具体对象编译器会自动推断对象的类型//泛型方法调用期间并没有给泛型参数赋值下面的案例是c1给t1赋值c2给t2赋值没有给T赋值。boolean equals MyUtil.equals(c1, c2);System.out.println(equals: equals);}
之后我们可以在main方法中创建两个对象并通过类名调用equals方法并打印结果。
4.泛型通配符
? 泛型通配符 表示不关心调用时传入的类型
/*** 将集合元素打印到控制台上*/public static void print(List? list){for(int i 0;ilist.size();i){System.out.println(list.get(i));}}
先定义一个方法将集合中的元素打印到控制台可以定义一个泛型的形参使用经典for循环遍历并打印出集合的每个元素
/*** 上边界的定义 ? extends 具体类名* 具体调用的时候可以是上边界的任何子类型或本类型* param list*/public static void print2(List ? extends Number list) {for(int i 0;ilist.size();i){System.out.println(list.get(i));}}
上边界的定义指的就是调用方法时需要传入的类型的形式只能时其本类型或者其子类型使用上边界时需要在形参传入泛型时改变extends 具体类型上边界之后的方法体不需要改变
/*** 下边界的定义 ? super 具体类名* 具体使用的时候可以是下边界的任何父类型或者本类型*/public static void print3(List ? super Integer list) {for(int i 0;ilist.size();i){System.out.println(list.get(i));}}
下边界的定义指的就是在调用方法时需要传入的类型的形式只能是其本类型或其夫类型传入的泛型需要改变为? super 具体类型下边界 public static void main(String[] args) {ListInteger nums new ArrayListInteger();nums.add(1);nums.add(2);nums.add(3);MyUtil.print(nums);//上边界的测试print2(new ArrayListLong());print2(new ArrayListNumber());//下边界的测试print3(new ArrayListInteger());print3(new ArrayListNumber());print3(new ArrayListObject());//没有关系
// print3(new ArrayListLong());}
在测试时首先建立一个Integer类型的集合并添加元素然后使用print方法打印
在测试上边界时定义的上边界是Number,我们传入的泛型可以是子类Long类型也可以是子类Integer也可以是本类Number
在测试下边界时定义的下边界是Integer,我们传入的泛型可以是父类Number类型也可以是父类Object也可以是本类Integer