泛型
泛型概述
泛型是啥? <字母>
1.一个<>里面泛型可以有多个,用逗号隔开即可,例如HashMap<K,V>,这就是有两个泛型
2.一个泛型中最好是单个字母且是大写字母
泛型的作用:
约束集合中元素的数据类型
特点:
1.只能使用引用数据类型去替换泛型存在的位置
2.泛型是在编译阶段存在的类型约束
3.如果有泛型,但是不去对泛型操作,去确定泛型类型的话,则泛型默认是Object类型
泛型的类型约束只在编译阶段存在
package com.tan.generic;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
System.out.println("list = " + list);
Class aClass = list.getClass();
Method add = aClass.getDeclaredMethod("add", Object.class);
add.invoke(list,"HelloWorld");
System.out.println("list = " + list);
}
}
泛型类
泛型类概述
作用:此类中就多了一种泛型类型给类使用,泛型类型的具体数据类型要等到具体使用这个类的时候才能确定
格式 :
public class 类名<泛型>{
}
泛型类使用样例
package com.tan.generic;
import java.util.Objects;
public class Student<E> {
private String name;
private E age;
public Student() {
}
public Student(String name, E age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public E getAge() {
return age;
}
public void setAge(E age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student<?> student = (Student<?>) o;
return Objects.equals(name, student.name) &&
Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.tan.generic;
public class GenericClass {
public static void main(String[] args) {
Student defaultStd = new Student();
defaultStd.setName("冰墩墩");
defaultStd.setAge(6);
Student<String> stringStd = new Student<>();
stringStd.setName("雪容融");
stringStd.setAge("5");
Student<Integer> integerStd = new Student<>();
integerStd.setName("谷爱凌");
integerStd.setAge(18);
}
}
泛型方法
泛型方法概述
泛型方法中的泛型一般用T表示
泛型方法一般都作为形参的数据类型使用, 但是方法泛型的具体类型等调用方法的时候才确定
格式:
方法的修饰符 <泛型> 返回值类型 方法名(形参列表){
方法体;
}
泛型方法使用样例
package com.tan.generic;
public class GenericMethod {
public static void main(String[] args) {
show("HelloWorld");
show(new Student());
}
public static <T> void show(T t){
System.out.println("t = " + t);
}
}
泛型接口
泛型接口概述
此类中就多了一种泛型类型给类使用,泛型类型的具体数据类型要等到具体使用这个类的时候才能确定
格式 :
public interface 接口<泛型>{
}
注意:
如果子类要沿用父类/父接口的泛型,子类必须也定义泛型
泛型接口使用样例
package com.tan.generic;
public class GenericInterface {
public static void main(String[] args) {
}
}
interface Grandmother<E>{
public abstract void add(E e);
}
interface Mother<E> extends Grandmother<E>{
}
class Daughter<E> implements Mother<E>{
@Override
public void add(E e) {
}
}
泛型的通配符和泛型的上下限
泛型的通配符和泛型的上下限概述
1.泛型的通配符:?
?可以接收任意的引用数据类型
2.泛型的上下限:
泛型的上限(<=):? extends 类名A
泛型的下限(>=):? super 类名A
类名的上下限都包含A类
泛型的通配符和上下限都是方法的形参上使用的
泛型的通配符及上下限使用样例
背景知识:在Java中,存在着Object > Number > Integer的关系
问题描述:
定义一个方法,使该方法可以接收ArrayList<Object>、ArrayList<Number>、
ArrayList<Integer>这三个类型的对象
有两种方式可以便捷实现以上需求:
1.泛型的通配符:?
其中?可以接收任意的引用数据类型
2.泛型的上下限:
泛型的上限(<=):? extends 类名A
泛型的下限(>=):? super 类名A
其中类名的上下限都包含A类
泛型的通配符和上下限都是方法的形参上使用的
package com.tan.generic;
public class Cola implements Comparable<Cola> {
@Override
public int compareTo(Cola o) {
return 0;
}
}
package com.tan.generic;
import java.util.ArrayList;
import java.util.Collections;
public class Generate {
public static void main(String[] args) {
ArrayList<Object> list1 = new ArrayList<>();
ArrayList<Number> list2 = new ArrayList<>();
ArrayList<Integer> list3 = new ArrayList<>();
wildcardMethod(list1);
wildcardMethod(list2);
wildcardMethod(list3);
boundMethod(list1);
boundMethod(list2);
ArrayList<Cola> cola = new ArrayList<>();
Collections.sort(cola);
}
public static void boundMethod(ArrayList<? super Number> list){
}
public static <T> void wildcardMethod(ArrayList<T> list){
}
}