认识泛型

  • 定义类、接口、方法时,同时声明了一个或者多个类型变量(如:)

  • 称为泛型类、泛型接口、泛型方法,它们统称为泛型。

    //例如:
    public class ArrayList<E>{
        ...
    }
    
  • 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力。

    可以避免强制类型转换,及其可能出现的异常。

  • 泛型的本质:把基本的数据类型作为参数传给类型变量。

泛型类

修饰符 class 类名<类型变量,类型变量,...>{   
}
//例如:
public class ArrayList<E>{
}
  • 注意:类型变量建议用大写英文字母,常用的有:**E **(Element元素类型)、T (Type返回值类型)、K (Key键类型)、V (Value值类型)等等。
自定义泛型类
  • 例如:模拟ArrayList集合自定义一个集合MyArrayList。

    //泛型类
    public class MyArrayList<E>{
        private ArrayList list= new ArrayList();
        
        public boolean add(E e){
            list.add(e);
            return true; //添加成功
        }
        
        public boolen remove(E e){
            return list.remove(e); //成功删除
        }
    }
    
    MyArrayList<String> list= new MyArrayList<>()
    list.add("Hello");
    //JDK7开始支持后面的类型可以不写
    

泛型接口

修饰符 interface 接口名<类型变量,类型变量,...>{
}
//例如:
public interface A<E>{
}
  • 注意:类型变量建议用大写英文字母,常用的有:**E **(Element元素类型)、T (Type返回值类型)、K (Key键类型)、V (Value值类型)等等。
自定义泛型接口
  • 需求:项目需要对学生/老师数据进行增删改查操作

    public interface Data<T>{
        void add(T t);
        void delete(T t);
        void change(T t);
        T search(int id);
    }
    
    public class StudentData implements Data<Student>{
        @Override
        public void add(Student student) {
        }
        @Override
        public void remove(Student student) {
        }
        @Override
        public void update(Student student) {
        }
        @Override
        public Student find(int id){
            return new Student();
        }
    }
    

泛型方法

修饰符 <类型变量,类型变量...> 返回值类型 方法名(形参列表){
}
自定义泛型方法
  • 需求:打印任意数组的内容。

    public class Test {
        public static void main(String[] args) {
            String[] names={"张三","李四","王五"};
            printName(names);
            System.out.println(getMax(names));
        }
        public static <T> void printName(T[] names){
            for(T name:names){
                System.out.println(name);
            }
        }
        public static <T> T getMax(T[] names){
            return names[0];
        }
    }
    

通配符

  • 就是"?",可以在“使用泛型”的时候代表一切类型;(E T K V 是在定义泛型的时候使用)

泛型的上下限

  • 泛型上限 ? extends T:能处理 T 类型或 T 的子类型

    • 用途: 用来读取数据。你从里面取出来的对象,至少是 T 类型,可以放心使用 T 的方法。
    • 限制: 不能往里面添加数据(除了 null),因为你不知道它具体是 T 还是 T 的哪个子类型,加进去可能会出错。
    public static void walk(ArrayList<? extends People>peoples){
    }
    
    • ? 能接收的必须是T或者其子类。
  • 泛型下限 ? super T:能接收 T 类型或 T 的父类型

    • 用途: 用来写入数据。任何 T 类型或 T 的子类型,都可以安全地放进 T 的父类型容器里。

    • 限制: 不能安全地读取数据(不能保证读出来的是什么具体类型),但可以读出来作为 Object

    • ? 能接受的必须是T或者其父类。

泛型支持的类型

  • 泛型不支持基本类型,只能支持对类型(引用数据类型)。

包装类

  • 包装类就是把基本类型的数据包装成对象的类型。

    基本数据类型 对于的包装类(引用数据类型)
    一般的数据类型 首字母大写
    int Integer
    char Character
    基本类型的数据包装成对象的方案(繁琐)
    public static Interger valueOf(int i)
    Integer it = Integer.valueOf(100);
    自动装箱:
    • 基本数据类型可以自动转换为包装类型。
    Integer it1 = 100;
    
    List<Integer> list = new ArrayList<>();
    int i = 10;
    list.add(Integer.valueOf(i));
    list.add(i); // 自动装箱
    
    自动拆箱:
    • 包装类型可以自动转换为基本数据类型。
    Integer obj = new Integer(10);
    int j = obj; // 自动拆箱:int j = obj.intValue();
    
包装类具备的其他功能
  • 可以把基本类型的数据转换为字符串类型。

    public static String toString(double d)
    public String toString()
    
    int i=1;
    String rs1=Integer.toString(i);
    
  • 可以把字符串类型的数值转换成数值本身对应的真实数据类型。

    public static int parseInt(String s)
    public static Integer valueOf(String s)
    
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐