Java学习4-1_泛型

一、 泛型

1 概述

Java泛型在J2 SE 1.5中引入,本质是参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。 这种参数类型可以用在接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

1.1 泛型类

/**
 * 泛型类
 */
//
public class ClassName<T> {
    
    
    private T data;

    public T getData() {
    
    
        return data;
    }
    public void setData(T data) {
    
    
        this.data = data;
    }
}

1.2 泛型接口

/**
 * 泛型接口
 */
public interface IntercaceName<T>{
    
    
    T getData();
}

1.2.1 泛型接口实现

//指定类型
public class Interface1 implements IntercaceName<String> {
    
    
    private String text;
    @Override
    public String getData() {
    
    
    	return text;
    }
}

//不指定类型
public class Interface1<T> implements IntercaceName<T> {
    
    
    private T data;
    @Override
    public T getData() {
    
    
        return data;
    }
}

1.3 泛型方法

private static <T> T methodName(T a, T b) {
    
    }

1.4 泛型限制类型

在使用泛型时,可以指定泛型的限定区域,比如必须是某个类的实现类,格式:

<T extends 类或接口1 & 接口2>

1.5 泛型中的通配符

类型通配符是使用 ?代替方法具体的类型实参。

  1. <? extends Parent>指定了泛型类型的上届
  2. <? super Child>指定了泛型类型的上届
  3. <?>指定了泛型类型的上届

1.6 作用

(1)泛化 (2)类型安全 (3)消除强制类型转换 (4)向后兼容

提高代码复用率;泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)

类型安全: 泛型的主要目标是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在非常高的层次上验证类型假设。没有泛型,这些假设就只存在于系统开发人员的头脑中。 通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误就可以在编译时被捕获了,而不是在运行时当作ClassCastException展示出来。将类型检查从运行时挪到编译时有助于Java开发人员更早、更容易地找到错误,并可提高程序的可靠性。

消除强制类型转换: 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。尽管减少强制类型转换可以提高使用泛型类的代码的累赞程度,但是声明泛型变量时却会带来相应的累赞程度。在简单的程序中使用一次泛型变量不会降低代码累赞程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低累赞程度。所以泛型消除了强制类型转换之后,会使得代码加清晰和筒洁。

泛型的运行效率:在非泛型编程中,将筒单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作非常频繁的系统中,这个特点带来的性能提升更加明显。

1.7 注意

  1. 在编译之后程序会采取去泛型化的措施。
  2. Java中的泛型,只在编译阶段有效。
  3. 在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加。
  4. 类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。
  5. 不要在泛型类中定义equals(Tx)这类方法,因为Object类中也有equals方法,当泛型类被擦除后,这两个方法会冲突。

1.8 泛型擦除

在编译期间,所有的泛型信息都会被擦除掉。

/**
 * 泛型擦除
 */
public class Test {
    
    
    public static void main(String[] args) {
    
      

        ArrayList<String> arrayList1=new ArrayList<String>();  
        arrayList1.add("abc");  

        ArrayList<Integer> arrayList2=new ArrayList<Integer>();  
        arrayList2.add(123);  

        System.out.println(arrayList1.getClass()==arrayList2.getClass()); //结果为true
    }  
}  

伪泛型问题,并不像C++的模板那样
看到一篇博客,有所体会,在此贴出链接
泛型的内部原理:类型擦除以及类型擦除带来的问题

问题:

  1. 使用泛型是否影响性能

    在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码,最多编译的时候也许会慢一些

猜你喜欢

转载自blog.csdn.net/Sky_Coolssy/article/details/108762140