栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

一文学懂java泛型

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一文学懂java泛型

一文学懂java泛型
  • 1.什么是java泛型
  • 2.泛型的快速入门
  • 3.拥有泛型特性的类
  • 4.泛型的使用细节
  • 5.自定义泛型类
  • 6.自定义泛型接口
  • 7.自定义泛型方法
  • 8.泛型通配符

1.什么是java泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

假定我们有这样一个需求:写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序,该如何实现?

答案是可以使用 Java 泛型。

使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序。然后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。


2.泛型的快速入门

代码示例:

import java.util.ArrayList;


public class Generics {
    public static void main(String[] args) {
        // 使用java泛型对数据类型做限制
        // 限制添加的类型必须为Dog
        ArrayList arrayList = new ArrayList();
        arrayList.add(new Dog("康康",12));
        arrayList.add(new Dog("旺旺",6));
        System.out.println(arrayList);
    }
}

class Dog {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

使用泛型,可以直接对于数据进行遍历,无需进行额外的类型强转,这增大了代码的效率:

for (Dog dog : arrayList) {
    System.out.println(dog.getName());
    System.out.println(dog.getAge());
}

3.拥有泛型特性的类

我们来创建一个类:

该类的一个属性为泛型,可以是任意的数据类型,在编译期间,确定E是什么类型

// 泛型类
class Person {
    E s; // 在编译期间,确定E是什么类型

    public Person(E s) { // E可以是参数类型
        this.s = s;
    }

    public E f() { // E也可以是返回类型
        return s;
    }
	@Override
    public String toString() {
        return "Person{" +
                "s=" + s +
                '}';
    }
}

那么我们在创建对象的时候,就可以传入不同的数据类型的数据,这很方便:

例如:

Person stringPerson = new Person("www");
System.out.println(stringPerson);
Person integerPerson = new Person(521);
System.out.println(integerPerson);
-------------------------------
输出:
Person{s=www}
Person{s=521}

4.泛型的使用细节

泛型的<>里面只能是引用类型,不可以为基本数据类型浪

在给泛型指定具体类型后,可以传入该类型或者该类型的子类型

在实际的开发中,我们一般采用简写的泛型语法(去掉后面<>里面的内容),例如:

Person doublePerson = new Person<>(13.14);

如果不给泛型指定具体的数据类型,默认为Object类型✨


5.自定义泛型类

泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。

和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。

  • 使用泛型的数组,不能初始化
  • 静态成员不能使用泛型,因为在类加载时,对象还没有创建,JVM无法完成其的初始化操作

接下来,我们看一个自定义泛型类的例子:

class Tiger {
    String name;
    R r;
    M m;
    T t;

    public Tiger(String name, R r, M m, T t) {
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public R getR() {
        return r;
    }

    public void setR(R r) {
        this.r = r;
    }

    public M getM() {
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

6.自定义泛型接口
  • 在接口中,静态成员也不能使用泛型
  • 泛型接口的类型,在继承接口或者实现接口的时候确定
  • 没有指定类型,默认依然为Object类型

自定义泛型接口的例子:

interface IUsb {
    R get(U u);

    void hi(R r);

    void run(R r1, R r2, U u1, U u2);

    default R method(U u) {
        return null;
    }
}

这个自定义泛型的接口,如果有接口想要继承他,可以在继承接口时指定泛型接口的类型:

interface IA extends IUsb{
    
}

现在当我们实现IA接口时,会用String和Double类型替换我们接口原有的U和R类型:

例如:

class TTT implements IA {

    @Override
    public Double get(String s) {
        return null;
    }

    @Override
    public void hi(Double aDouble) {

    }

    @Override
    public void run(Double r1, Double r2, String u1, String u2) {

    }
}

当然,我们也可以在实现接口的同时指定接口的数据类型,例如:

class III implements IUsb {

    @Override
    public String get(Integer integer) {
        return null;
    }

    @Override
    public void hi(String s) {

    }

    @Override
    public void run(String r1, String r2, Integer u1, Integer u2) {

    }
}

7.自定义泛型方法
  • 泛型方法,可以定义在普通类中,也可以定义在泛型类中
  • 泛型方法在调用时,类型就确定了

使用代码示例:

public class AdvancedGenerics {
    public static void main(String[] args) {
        fly("保密",521);
        fly(12,true);
    }

    
    static public  void fly(T t, R r) {
        System.out.println(t);
        System.out.println(r);
    }
}
---------------------------
输出:
保密
521
12
true

8.泛型通配符

泛型不具备继承性

类型通配符一般是使用 ? 代替具体的类型参数。例如 List 在逻辑上是List,List等所有 List<具体类型实参> 的父类

public static void printCollection(List c){
    for (Object o : c) {
        System.out.println(o);
    }
}

表示该通配符所代表的类型是T类型的子类。
表示该通配符所代表的类型是T类型的父类。

public static void printCollection2(Listc){
    for (AA aa : c) {
        System.out.println(aa);
    }
}


public static void printCollection3(Listc) {
    for (Object o : c) {
        System.out.println(o);
    }
}

知识给人重量,成就给人光彩,大多数人只是看到了光彩,而不去称量重量。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1031207.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号