关于Java中的泛型

一:认识泛型

1.定义类,接口,方法时,同时声明了一个或者多个类型变量(如:<E>),称为泛型类,泛型接口,泛型方法,它们统称为泛型。

如果并没有在<>内限制数据类型 那么它默认就是object类。

如果限制了数据类型则只能添加相对应类型的变量。注意:<>内只能添加引用数据类型 不能添加基本数据类型。

2.作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。

3.泛型的本质:把具体的数据类型作为参数传给类型变量。

二:自定义泛型类

1.正常单个数据类型 相当于ArrayList集合 和其作用相似。

public class A<E> {
    public Object[] arr = new Object[10];//设置一个数组来储存添加的数据
    public int size;//记录当前数据的位置
    public boolean add(E e){
        arr[size++] = e;//对当前位置的数组进行赋值
        return true;
    }
    public E get(int index){
        return (E)arr[index];//得到索引位置的数据
    }
}

2.多个数据类型 可以声明多个类型变量。

public class B<M, N> {
    public boolean put(M m, N n){
        return true;
    }
}

3.继承型数据类型 <>内数据类必须要是继承于或等于指定的类才不报错。

public class C<A extends Animal> {}

public class Dog extends Animal{}

public class Cat extends Animal{}

C<Cat> c = new C();
C<Dog> c2 = new C();
C<Animal>c3 = new C();
C<String> c4 = newC();//会报错

三:泛型接口

1.使用

import java.util.ArrayList;

public interface Date<D> {
    void add(D d);
    ArrayList<D> getbyName(String name);
}

public class Student {
    String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

import java.util.ArrayList;

public class StudentDate implements Date<Student>{
    @Override
    public void add(Student student) {

    }

    @Override
    public ArrayList<Student> getbyName(String name) {
        return null;
    }
}

public class DateTest {
    public static void main(String[] args) {
        Date<Student> s = new StudentDate();
        s.add(new Student("王凯"));
        s.add(new Student("蔡建宇"));
        s.add(new Student("余洋"));
        s.add(new Student("樊军鑫"));
        s.getbyName("王凯");
    }
}

实现泛型接口,分为两种情况:第一种情况:子类清楚的知道 泛型参数的类型;第二种情况:子类不知道是什么类型 。

//第一种情况
/*public class InterImpl implements Inter<String>{
    @Override
    public void show(String t) {
        System.out.println(t);
    }
}*/



//第二种情况
public class InterImpl<T> implements Inter<T>{
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

/*
 * 泛型接口测试
 */
public class InterGenericTest {

    public static void main(String[] args) {
        //第一种情况测试
        //        Inter<String> i=new InterImpl();
        //        i.show("123");

        //第二种情况测试
        Inter<String> ii=new InterImpl<String>();
        ii.show("java");
    }
}

注意:泛型接口也可以继承其他类

四:泛型方法

1.泛型方法的使用:

import java.util.ArrayList;

public class TEST  {
    public static void main(String[] args) {
        String rs = test("算了吧");
        System.out.println(rs);

        Dog d = test(new Dog());

        ArrayList<Car> cars = new ArrayList<>();
        cars.add(new Car());
        cars.add(new Car());
        go(cars);

        ArrayList<BMW> bmws = new ArrayList<>();
        bmws.add(new BMW());
        bmws.add(new BMW());
        go(bmws);

        ArrayList<BENZ> benzs = new ArrayList<>();
        benzs.add(new BENZ());
        benzs.add(new BENZ());
        go(benzs);
    }
    //    public static <T> void go(ArrayList<T> cars){
    //
    //    }不限定类型的用法
    //      public static <T extends Car> void go(ArrayList<T> cars){
    //
    //      }限定类型的用法
    public static void go(ArrayList<?> cars){

    }//不限定类型的用法
    //      public static void go(ArrayList<? extends Car> cars){
    //        
    //      }限定类型的用法

    public static <T> T test(T t){
        return t;
    }
}

2.通配符:就是"?",可以在"使用泛型"的时候代表一切类型;E T K V是在定义泛型的时候使用。

3.泛型的上下限:

泛型上限:? extends Car ?能接收的必须是Car或者其子类

泛型下限: ? super Car ?能接收的必须是Car或者其父类

五:泛型的擦除问题和注意事项

1.泛型是工作在编译阶段的,一旦编译成class文件,class文件中就不存在泛型了,这就是泛型擦除。

2.泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。

Java泛型通配符用于解决类型安全问题,并提供了一种方法来引用类型,而不需要知道具体的类型参数。通配符主要有以下几种形式: 1. `?`:无界通配符,表示未知的类型,可以匹配任何对象的类型。 2. `<? extends 类或接口>`:表示具体的类型,但不是确定的类型。`extends`在这里的意思是“某种类型的子类”。这可以用来限定类型参数的上界,只允许该通配符引用某个类型或其子类型。 3. `<? super 类或接口>`:表示具体的类型,但不是确定的类型。`super`在这里的意思是“某种类型的父类”。这可以用来限定类型参数的下界,只允许该通配符引用某个类型或其父类型。 4. `? extends 类型1 & 类型2 & ... & 类型n>`:表示有限制的通配符,可以引用同时满足多个上限类型约束的类型。 使用泛型通配符的目的是为了增强代码的灵活性,同时保证类型安全。例如,如果有一个泛型方法需要接受任何类型的`List`作为参数,但不想限制这个`List`只能包含特定类型的对象,那么可以使用无界通配符`<?>`。 下面是一个简单的例子,来说明如何使用泛型通配符: ```java public class GenericWildcardExample { public static void processElements(List<?> elements) { for (Object element : elements) { // 处理元素,但不知道元素的实际类型 } } } ``` 在这个例子,`processElements`方法可以接受任何类型的`List`对象作为参数,但在方法内部,我们只能将元素当作`Object`类型来处理。 使用泛型通配符的注意事项: - 不能实例化泛型通配符。 - 不能使用带有泛型通配符的类型作为方法的参数类型,因为这会导致在调用时出现类型安全问题。 - 如果要向泛型集合添加元素,那么只能添加`Object`类型的元素,因为编译器不知道集合具体存储的是哪种类型的对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值