Java中的泛型

目录

一、泛型是什么?

二、泛型的本质?

三、泛型的好处有哪些?

四、泛型的用法

1、泛型类

2、泛型接口

3、泛型方法

4、自定义泛型

五、上限通配符

六、下限通配符


一、泛型是什么?

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

二、泛型的本质?

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

相当于告诉编译器每个集合接收的对象类型是什么,编译器在编译期就会做类型检查,使得程序更加安全,增强了程序的健壮性

//就是将list集合根据数据类型进行分类,一个list只存储指定类型的元素
        ArrayList<String> l1=new ArrayList<String>();
        ArrayList<Integer>l2=new ArrayList<Integer>();

三、泛型的好处有哪些?

1.泛型的指定可以使运行时期的问题提前到编译器,避免了数据强转可能出现的问题。

2.避免了装箱和拆箱带来的影响性能问题。

若不指定泛型,默认是object类型。输出时就要进行强转

装箱:任意类型的元素---->object类型

拆箱:object----->需要的元素类型。

3.泛型可以以提高代码的复用性(可以对方法进行抽取,并将类型参数化,由调用者进行传入所需的类型),提高开发效率。

四、泛型的用法

泛型可以使用在类,接口,方法上

参数类型的规范,一般是使用单个大写字母表示

E:Element(元素)

T:Type(类型)

K:Key(键)

V:Value(值)

N:Number(数值类型)

?:通配

1、泛型类

格式:public class 类名 <泛型类型1,...> { }

public class MyGenerics<T> {
    private T type;

    public T getType() {
        return type;
    }

    public void setType(T type) {
        this.type = type;
    }
//构造方法,在创建该类对象时就要指定type
    public MyGenerics(T type) {
        this.type = type;
    }
    
    public static void main(String[] args) {
        GenericClass<String> g1 = new GenericClass<>("string");
        System.out.println(g1.getType());
        GenericClass<Integer> g2 = new GenericClass<>(1);
        System.out.println(g2.getType());
    }
}

运行结果 

2、泛型接口

格式:public <泛型类型> 返回类型 方法名(泛型类型 变量名) { }

public interface MyGenericInterface<T> {
    // 获取值
    T getValue();

    // 设置值
    void setValue(T value);
}

class MyClass<T> implements MyGenericInterface<T> {
    private T value;

    // 实现获取值方法
    @Override
    public T getValue() {
        return value;
    }

    // 实现设置值方法
    @Override
    public void setValue(T value) {
        this.value = value;
    }

    public static void main(String[] args) {
        // 创建一个MyClass对象,并指定泛型类型为String
        MyClass<String> myStringClass = new MyClass<>();

        // 设置值为字符串
        myStringClass.setValue("Hello, generics!");

        // 获取值并打印
        String stringValue = myStringClass.getValue();
        System.out.println("String value: " + stringValue);

        // 创建一个MyClass对象,并指定泛型类型为Integer
        MyClass<Integer> myIntegerClass = new MyClass<>();

        // 设置值为整数
        myIntegerClass.setValue(42);

        // 获取值并打印
        int intValue = myIntegerClass.getValue();
        System.out.println("Integer value: " + intValue);
    }
}

运行结果

3、泛型方法

通常情况下,当一个方法的形参不确定的情况下,我们会使用到泛型方法。

定义格式:修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }

public class MyGenericMethod {
    // 泛型方法,用于比较两个对象是否相等
    public static <T> boolean isEqual(T obj1, T obj2) {
        return obj1.equals(obj2);
    }

    // 泛型方法,用于打印数组中的所有元素
    public static <E> void printArray(E[] array) {
        for (E element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // 使用isEqual方法比较整数
        System.out.println("是否相等:" + isEqual(10, 10));
        System.out.println("是否相等:" + isEqual("hello", "world"));

        // 使用printArray方法打印整数数组和字符串数组
        Integer[] intArray = {1, 2, 3, 4, 5};
        String[] stringArray = {"apple", "banana", "orange"};
        System.out.print("Integer Array: ");
        printArray(intArray);
        System.out.print("String Array: ");
        printArray(stringArray);
    }
}

运行结果

4、自定义泛型

一般在写项目是会使用到自定义泛型,也就是自己封装一个类,类里填写所需要的字段

也就是实体类,将对象存入到集合中

public static void main(String[] args) {
        //创建学生1
        Student student1 = new Student();
        student1.setName("学生1");
        student1.setAge(10);
        //创建学生2
        Student student2 = new Student();
        student2.setName("学生2");
        student2.setAge(12);
        ArrayList<Student> students=new ArrayList<>();
        //添加到list
        students.add(student1);
        students.add(student2);
        //输出list
        System.out.println(students);
        //遍历集合
        for (Student student : students) {
            System.out.println(student);
        }
    }

运行结果

五、上限通配符

<? extends 类> 表示?可以指代任何类型,但是该类型必须是后面类的子类。

import java.util.ArrayList;
import java.util.List;
 
public class WildcardBoundsExample {
    public static void main(String[] args) {
        List<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
 
        // 以下限定了通配符的类型必须是Number或其子类
        printList(integers);
    }
 
    private static void printList(List<? extends Number> list) {
        for (Number number : list) {
            System.out.println(number);
        }
    }
}

六、下限通配符

<? super 类> 此时?表示可以指代任意类型,但是该类型必须是后面类的父类。

import java.util.ArrayList;
import java.util.List;
 
public class WildcardBoundsExample {
    public static void main(String[] args) {
        List<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
 
        // 以上限定了通配符的类型必须是Number或其父类
        addToList(integers, 4);
    }
 
    private static void addToList(List<? super Integer> list, Integer item) {
        list. Add(item);
    }
}

在这两个示例中,我们定义了一个方法printList,它接受一个List<? extends Number>类型的参数。这意味着我们可以传递任何Number类型或其子类型的List。同样地,我们定义了一个方法addToList,它接受一个List<? super Integer>类型的参数。这意味着我们可以传递任何Integer类型或其父类型的List。

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值