Java基础之泛型

Java基础01-泛型详解

一、为什么要使用泛型

在java1.5之前,如果想通过一种通用的方法完成对不同参数的调用,那么只能通过创建Object数组来加入不同类型的参数变量。

 Object[] element=new Object[10];
 添加数字:
 element.add(1);
 添加字符串:
 element.add("abc");

但是这样就会出现几个问题

1.元素加入object数组后,元素将以object类型存放在数组中,这时如果我们需要取出使用该元素,就必须对其进行强制类型转换。

2.由于任何类型的元素都可以存入object数组,因此在我们无法确定存入元素类型的情况下,取出时就需要进行类型转换。但这样会出现一个问题,当我们忘记进行类型转换时,编译器不会报错,但在运行时却会出现异常。我们希望在编译时就能发现错误,来提高效率,因此泛型便诞生了。

二、泛型的使用

泛型可以分为以下几种

1.泛型类

class Example<T>{
   private T key;
   public Example(T key){
        this.key=key;
   }
   public T getKey(){
        return key;
   }
}

Example <Integer> exInt=new Example <Integer>(123);
Example <String>  exStr=new Example <String>("qwe");
System.out.println(exInt.getKey());
System.out.println(exStr.getKey());

注:泛型的类型参数只能是类类型而不能是基本数据类型,原因在于泛型要求包容的是对象类型,而基本数据类型不属于。不过我们可以通过基本类型的封装类来存放基本类型,八大基本类型的封装类如下:

简单类型booleanbytecharshortintlongfloatdouble
二进制位数18161632643264
封装器类BooleanByteCharacterShortIntegerLongFloatDouble

2.泛型接口

interface a1<T>{
   public T next();
}

关于接口的实现:

1.当无泛型实参时

class a2<T> implements a1<T>{}

2.当有泛型实参时

class a3 implements a1<String>{}

3.类型通配符

(1).提出

​ 假如我们需要定义一个方法,方法中有一个集合形参,而我们不知道其数据类型,这时就需要用到类型通配符了。

(2).使用

通配符包括:

a.无限定通配符

​ <?>

例如 List<?>,“?”可以表示任何类型,即也可以表示未知类型。

区别 List<?>和List,二者并不等同:

List<?>是所有泛型类型的父类,任何引用类型的List都可以传入,其类型是Object。但不能向其中添加对象,除了null。

为什么不能添加对象?

举个栗子:

List<String> l1=new ArrayList<String>();
List<?> l2=l1;
l1.add("abc");         //正确
l2.add("abc");         //错误

现在我们假设l2.add("abc"); 是正确的
那么 l2.add(123); 也是正确的
由于把l1赋值给了l2,那么l1和l2便指向了同一块内存地址,但是l1只能存放String类型的对象,如果l2可以存放String类型,那么l2也可以存放Integer类型,这和l1定义的类型发生了冲突。

List是具体化的泛型,只能是引用数据类型,可以在其中添加Object类及其子类对象。

b.上边界通配符

Vector<? extends 类型1> x=new Vector<类型2>();

其中,类型2和类型1一致或类型2为类型1子类。

c.下边界通配符

Vector <? super 类型1> x=new Vector<类型2>();

其中,类型2和类型1一致或类型2为类型1父类。

4.泛型方法

(1).无返回值类型

public <T> void text(T t3){
      T  t3=t3;
}

(2).有返回值类型

public <T> text(T t3){
     T   t3=t3;
     return t3;
}

注:泛型方法必须要有public 标识符

举个栗子

public class Test {
    static class Fruit{
        public String toString(){
            return "Fruit";
        }
    }
    static class Apple extends Fruit{
        public String toString(){
            return "Apple";
        }
    }
    static class Person{
        public String toString(){
            return "Person";
        }
    }

    static class Test1<T>{
        //这不是泛型方法
        public void show(T t){
            System.out.println(t.toString());
        }
        
        //这是泛型方法
        public <T> void show2(T t){
            System.out.println(t.toString());
        }
    }

    public static void main(String[] args) {
        Apple apple=new Apple();
        Person person=new Person();

        Test1<Fruit> test=new Test1<Fruit>();
        test.show(apple);         //正确,因为apple是Fruit的子类
        test.show(person);        //错误
        
        test.show2(apple);
        test.show2(person);      //二者都正确
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值