泛型

泛型概念

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

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

泛型的引入

  • 问题:

比如我们实现一个顺序表,只能保存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是在实例化一个对象确定的,静态属性和方法中也就不能带泛型参数,不依赖于对象,

已标记关键词 清除标记
相关推荐
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页