Java 泛型

Java的泛型是JDK5引入的新特性,它允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。泛型可以应用于类、接口和方法,用于指定操作的数据类型。在运行时,由于类型擦除,泛型并不实际存在,但在编译阶段能有效防止类型转换异常。此外,泛型通配符如?extendsE和?superE用于限制参数类型,增加代码的灵活性。
摘要由CSDN通过智能技术生成

泛型

泛型深入

泛型:jdk5新特性,可以在编译阶段约束操作的数据类型,并进行检查
泛型的格式:<数据类型>
注意:泛型只能支持引用数据类型

泛型的好处:

  • 统一数据类型
  • 把运行时期的问题提前到了编译期间,避免开了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来
    扩展知识点:Java中的泛型是伪泛型
    java文件(是有泛型的)–泛型的擦除–class文件(没有泛型,都是Object强转)

泛型的细节

  • 泛型中不能写基本数据类型
  • 指定泛型的具体类型后,传入数据时,可以传入该类型或者其子类类型
  • 如果不写泛型,类型默认是Object

泛型可以在很多地方进行定义

类后面(泛型类)

格式:修饰符 class 类名<类型>{}
举例:public class ArrayList<E>{} 创建该类对象时,E就确定类型
此处E可以理解为变量,但不是用来记录数据的,而是记录数据类型的
	可以写成:T(type)  、E(element)  、K(key)  、V(value)

使用场景:当一个类中,每个变量的数据类型不确定时,就可以定义带有泛型的类

package com.mygenerics;

import java.util.Arrays;

public class MyArrayList <E>{

    Object[] obj = new Object[10];
    int size;

    public boolean add(E e){
        obj[size] = e;
        size++;
        return true;
    }

    public E get(int index){
        return (E)obj[index];
    }

    @Override
    public String toString () {
        return Arrays.toString (obj);
    }
}

package com.mygenerics;

public class GenericsDemo02 {
    public static void main (String[] args) {
        MyArrayList<String> list = new MyArrayList<> ();

        list.add ("aaa");
        list.add ("bbb");
        list.add ("ccc");
        list.add ("ddd");

        System.out.println (list);

        MyArrayList<Integer> list2 = new MyArrayList<> ();

        list2.add (1);
        list2.add (3);
        list2.add (2);
        list2.add (4);

        int get = list2.get (1);
        System.out.println (get);

        System.out.println (list2);
    }
}

方法上面(泛型方法)

此时泛型写的什么类型,那么就只能传递什么类型的数据
 弊端:
    利用泛型方法有个小弊端,此时它可以接受任意的数据类型

接口上面(泛型接口)

泛型通配符

    ?表示不确定的类型
    它可以进行类型的限定
    ?Extends E 表示可以传递E或者E 的所有的子类类型
    ? super E :表示可以传递E或者E所有的父类类型
 应用场景:
    1. 如果我们在定义类、方法、接口的时候,如果类型不确定,姐可以定义泛型类、泛型方法、泛型接口
    2. 如果类型不确定,但是能知道只能传递某个继承体系中的,就可以使用泛型通配符
 泛型的通配符
    关键点:可以限定类的范围
package com.mygenerics;

import java.util.ArrayList;

public class GenericsDemo04 {
    public static void main (String[] args) {

        /*
            需求:定义一个方法,形参是一个集合,但是集合中的数据类型不确定
         */

        //创建集合的对象
        ArrayList<Ye> list1 = new ArrayList<> ();
        ArrayList<Fu> list2 = new ArrayList<> ();
        ArrayList<Zi> list3 = new ArrayList<> ();

        ArrayList<Student2> list4 = new ArrayList<> ();

        //调用method方法
        method(list1);
        method(list2);
        method(list3);
        method (list4);
    }
    /**
    此时泛型写的什么类型,那么就只能传递什么类型的数据
     弊端:
        利用泛型方法有个小弊端,此时它可以接受任意的数据类型

     希望:虽然不确定类型,但是只希望他传递 Ye Fu Zi

     此时我们就可以使用泛型的通配符
        ?表示不确定的类型
        它可以进行类型的限定
        ?Extends E 表示可以传递E或者E 的所有的子类类型
        ? super E :表示可以传递E或者E所有的父类类型

     应用场景:
        1. 如果我们在定义类、方法、接口的时候,如果类型不确定,姐可以定义泛型类、泛型方法、泛型接口
        2. 如果类型不确定,但是能知道只能传递某个继承体系中的,就可以使用泛型通配符
     泛型的通配符
        关键点:可以限定类的范围

    */
    public static<E> void method(ArrayList<? extends Ye> list){

    }
}
class Ye{

}

class Fu extends Ye { }

class Zi extends Fu {

}
class Student2{}

综合练习

在这里插入图片描述

package com.mygenerics.test;

import java.util.Objects;

public abstract class Animal {
    private String name;
    private int age;

    public abstract void eat();

    public Animal () {
    }

    public Animal (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 "Animal{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
    

    @Override
    public int hashCode () {
        return Objects.hash (name, age);
    }
}

package com.mygenerics.test;

public abstract class Cat extends Animal{
}

package com.mygenerics.test;

public class Persian extends Cat{
    @Override
    public void eat () {
        System.out.println ("一只叫做"+getName ()+"的"+getAge ()+"岁波斯猫,正在吃小饼干");
    }
}

package com.mygenerics.test;

public class Civet extends Cat{
    @Override
    public void eat () {
        System.out.println ("一只叫做"+getName ()+"的"+getAge ()+"岁狸花猫,正在吃鱼");
    }
}

package com.mygenerics.test;

public abstract class Dog extends Animal{
}

package com.mygenerics.test;


public class Teddy extends Dog {
    @Override
    public void eat () {
        System.out.println ("一只叫做"+getName ()+"的"+getAge ()+"岁泰迪,正在吃骨头,边吃边蹭");
    }
}

package com.mygenerics.test;

public class Husky extends Dog{
    @Override
    public void eat () {
        System.out.println ("一只叫做"+getName ()+"的"+getAge ()+"岁哈士奇,正在吃骨头,边吃边拆家");
    }
}

package com.mygenerics.test;

import java.util.ArrayList;

public class Test {
    public static void main (String[] args) {

        ArrayList<Persian> list1 = new ArrayList<> ();
        ArrayList<Civet> list2 = new ArrayList<> ();
        ArrayList<Husky> list3 = new ArrayList<> ();
        ArrayList<Teddy> list4 = new ArrayList<> ();

        keepPet (list1);
        keepPet (list2);
        keepPet (list3);
        keepPet (list4);
    }


     //该方法能养所有的动物,但是不能传递其他类型
    public static void keepPet(ArrayList<? extends Animal> list){
        //遍历集合,调用动物的eat() 方法
    }

    /**
     * 该方法能养所有的猫,但是不能养狗
     * public static void keepPet(ArrayList<? extends Cat> list){

    }*/
    /**
     * 该方法能养所有的狗,但是不能养猫
     * public static void keepPet(ArrayList<? extends Dog> list){

    }*/
}

总结

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只理智汪

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值