欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java 泛型的一些理解

程序员文章站 2024-03-14 18:14:34
...

查阅了网上的资料 和《java编程思想》相关链接见底部。Java1.5开始引入的,常见的使用泛型的就是容器类这样容器可以任意装载数据。

没有泛型之前容器类是怎实现的?

没有泛型的情况下,假设一个方法希望能够传入一个任意类型的参数那么我肯定会这么写

class A{
    private Object o;
    public void set(Object o){
        this.o = o;
    }
    public Object get(Object o){
        return this.o;
    }
}

通过使用Object作为参数类型就可以实现任意类型的参数的传入,但是还有个问题就是取出来的对象也是Object(这种情况叫做类型擦除)。这个时候需要手动的Object转换成原来的类型,这种手工活比较繁琐吧,还有就是会有异常。

泛型怎么实现任意装载数据

通过Object类作为参数

将使用泛型的class文件反编译会看到所有T类型都被替换成了Object。说明泛型也是通过上面的方式实现接收任一数据的,然后再取出的时候将类型转换回来。

泛型的好处

  • 隐式转换
    泛型的好处在于隐式的擦除了具体的数据类型全部变成了Object类型,但是在取出的时候隐式的将Object类型转换成了具体的类型。编译器实现了类型擦除和类型还原的过程,所以得泛型的好处就是替换了手工的工作而且更高效和安全,而且泛型传入必须对象类型不能是数据基本类型。
  • 自我限定
class A {
}

class B extends A {
}

class C<T> {
    private T t;

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

    public static void main(String[] args) {
        C<A> c = new C();
        c.set(new B())
    }
}

将上面的代码编译成class后,会发现C中T被替换成了A,然后C中只能传入A或者A的子类。这就是泛型的自我限定。这种特性的好处就是限定传入的参数的边界,可以指定我们需要的传入类型。

为啥数组不能使用泛型

这篇文章讲的比较清楚了分析一下为什么JAVA不支持泛型类型的数组

泛型的使用

泛型接口

B类实现接口A时必须想下面这样将泛型参数传递给A,才能在B实现A中set方法的参数设为泛型参数。否则A的set方法参数将会是Object类型。

    public interface A <T>{
        void set(T t);
    }

    public class B<T> implements A<T> {
        @Override
        public void set(T t) {

        }
    }

泛型参数可以定义任意个

泛型参数是可以定义任意个的所以上面代码的B类除了传递给接口的T类型,还可以定义其他泛型参数

    public class B<T,D,C> implements A<T> {
        private D d;
        private C c;
        @Override
        public void set(T t) {

        }
    }

泛型类

    public class B<T>  {
        public void set(T t) {

        }
    }

    public class D<T> extends B<T>  {
        public void set(T t) {

        }
    }

泛型方法

    public <H> void set(H data) {
    }

    public I<I> set(I data) {
        return null;
    }

自限定类型(通配符)

? 表示不确定的java类型。
T 表示java类型。
K V 分别代表java键值中的Key Value。
E 代表Element。

相关链接

深入理解Java之泛型
java泛型详解