泛型

泛型概念

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),
然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,
操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

泛型的引入

  • 问题:

比如我们实现一个顺序表,只能保存int类型的元素,如果我们想要保存指向Person类型对象的引用,又或者想要保存一个Book对象类型的引用,如何解决?

  • 回答

我们很在然的就会想到将我们的元素类型定义为Object类型,那么Object类型的引用就可以指向Personl类型的对象或者Book类型的对象

public class MyArrayList { 
private Object[] array; // 保存顺序表的元素,即Object 类型的引用
private int size; // 保存顺序表内数据个数 
public void add(Object o) { 尾插 } 
public Object get(int index) { 获取 index 位置的元素 }

这样我们就可以很自由的将任意对象引入到我们的顺序表

MyArrayList books = new MyArrayList(); 
for (int i = 0; i < 10; i++) { 
	books.add(new Book()); // 尾插 10 本书到顺序表 
}
MyArrayList people = new MyArrayList(); 
for (int i = 0; i < 10; i++) { 
	people.add(new Person()); // 尾插 10 个人到顺序表 
}

现在MyArrayList可以添加任意类型的引用到其中了但会产生以下问题

MyArrayList books = new MyArrayList(); books.add(new Book); 
// 将 Object 类型转换为 Person 类型,需要类型转换才能成功 
// 这里编译正确,但运行时会抛出异常 ClassCastException 
Person person = (Person)books.get(0));

因此,为了

  1. 增加编译期间的类型检查
  2. 取消类型转换的使用

泛型就此诞生

泛型的分类

  • 泛型方法
定义:
<>是泛型的标志
//E是类型变量名 变量名一般大写
public static <E> 返回值类型 方法名称(参数列表){
	.......
}
调用:

类名.<实际类型> 方法名称(参数列表)
类名. 方法名称(参数列表)

注意:调用时泛型可以省络。编译器会自动识别

泛型实现一个对象冒泡排序

Teacher类

public class Teacher {
    public String name;
    public int age;
    public int height;

    public Teacher(String name, int age, int height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

TeacherByAgeCompartor类(实现按年龄比较的比较器)

import java.util.Comparator;

public class TeacherByAgeCompartor implements Comparator<Teacher> {
    @Override
    public int compare(Teacher o1, Teacher o2) {
        return o1.age-o2.age;
    }
}

GenericMethodDemo类(实现泛型魔炮排序)

import java.util.Arrays;
import java.util.Comparator;

public class GenericMethodDemo {
        //泛型定义冒泡排序
        public static <T>void bubbleSort(T[] array, Comparator<T> comparator){
            for (int i = 0; i < array.length - 1; i++) {
                for (int j = 0; j < array.length - i - 1; j++) {
                    // T 实际上是什么类型
                    // Teacher/Student 引用类型

                    int r = comparator.compare(array[j], array[j + 1]);
                    if (r > 0) {
                        // 代表 array[j] 指向的对象   "大于"   array[j + 1] 指向对象
                        T t = array[j];
                        array[j] = array[j + 1];
                        array[j+1] = t;
                    }
                }
            }
        }

    public static void main(String[] args) {
        Teacher[] teachers = {
                new Teacher("张三", 18, 180),
                new Teacher("李四", 34, 190),
                new Teacher("王五", 16, 200),
                new Teacher("六子", 16, 170)
        };
        Comparator<Teacher> byAge = new TeacherByAgeCompartor();
        //泛型方法调用
        GenericMethodDemo.<Teacher>bubbleSort(teachers, byAge);
        //也可以不写编译器会识别
        GenericMethodDemo.bubbleSort(teachers, byAge);
        System.out.println(Arrays.toString(teachers));
    }
}

  • 泛型类
//<>是泛型的标志
//E是类型变量名 变量名一般大写
 public class MyArrayList<E> { 
 	private E[] array; 
 	private int size; 
 	... 
 }

注意: 泛型类可以一次有多个类型变量,用逗号分割。

  1. 泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
  2. 泛型代码在运行期间,就是我们上面提到的,利用 Object 达到的效果

泛型总结

  1. 泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
  2. 泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
  3. 泛型是一种编译期间的机制,即 MyArrayList 和 MyArrayList 在运行期间是一个类型。
  4. 泛型就是java中的一种合法语法标志就是<>
  5. 泛型中的类型变量一定是引用数据类型不能是基本数据类型
  6. 泛型类种不能包含有泛型参数的静态属性和方法
class A<T>{
	T a;//正确
	void method(T b){...}//正确
	static T c;//错误
	static void method(T d){...}//错误
}

T是在实例化一个对象确定的,静态属性和方法中也就不能带泛型参数,不依赖于对象,

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值