Java泛型机制必要性及原理解析

泛型程序设计(Generic Programming)

“使用泛型机制编写的程序代码要比那些杂乱地使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性。泛型对于集合类尤其有用。”

1.意义、必要性、重要性

泛型程序设计 意味着编写的代码可以被很多不同类型的对象所重用。例如,我们并不希望为聚集String和File对象分别设计不同的类。实际上,也不需要这样做,因为一个ArrayList类就可以聚集任何类型的对象。这是一个泛型程序设计的实例。

事实上,在Java增加泛型机制前就存在一个ArrayList类。下面借助ArrayList类的演变来说明Java引入泛型机制到底有重要。

在Java引入泛型类之前,ArrayList类将维护一个Object引用的数组:

public class ArrayList{
  private Object[] elementData;
  ...
  public Object get(int i){...}
  public void add(Object o){...}
}

使用这种ArrayList类存在两个问题:

每获取一个值都必须进行强制类型转换。

ArrayList files = new ArrayList();
...
String fileName = (String) files.get(0);

由于没有错误检查,可以插入任意类型的对象。

files.add(new File("..."));

对于上面的操作,编译和运行的时候都不会出错。然而,当其他地方取出该数据,并试图进行强制类型转换时就会产生一个错误。

ArrayList files = new ArrayList();
//不报错
files.add(new File("..."));
//报错
String fileName = (String) files.get(0);

对于上面提到的两个问题,泛型提供了一个很好的解决方案:类型参数(type parameters)。在ArrayList类中使用一个类型参数来指示元素的类型:

public class ArrayList<E>{
  private Object[] elementData;
  ...
  public E get(int i){...}
  public void add(E o){...}
}

ArrayList<String> files = new ArrayList<>();

这使得代码具有更好的可读性,人们一看就能知道这个数组列表中包含的是String对象。

同时,编译器也可以很好的利用这个信息。当调用get方法时,因为编译器已经知道返回值是String类型,所以不在需要进行强制类型转换。当调用add方法时,编译器因为知道add方法的参数是String类型,可以对add方法的使用进行检查,避免调用者传入错误类型的参数。

在编译时就发现错误比运行时才发现错误要好得多*,类型参数的魅力在于:使得程序具有更好的可读性和安全性。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java泛型类与泛型方法的定义详解

    本文实例讲述了Java泛型类与泛型方法的定义.分享给大家供大家参考,具体如下: Java泛型类的定义 一 点睛 泛型类定义的语法如下: [访问修饰符] class 类名称 <T> 泛型类的主要作用在于类被实例化后,传入具体的类型参数,对类的成员属性的类型和成员方法的参数类型和返回值类型进行替换. 二 代码 public class Base<T> { T m; Base(T t) { m = t; } public T getM(){ return m; } public void

  • Java中泛型通配符的使用方法示例

    本文实例讲述了Java中泛型通配符的使用方法.分享给大家供大家参考,具体如下: 一 点睛 引入通配符可以在泛型实例化时更加灵活地控制,也可以在方法中控制方法的参数. 语法如下: 泛型类名<? extends T> 或 泛型类名<? super T> 或 泛型类名<?> ? extends T:表示T或T的子类 ? super T:表示T或T的父类 ?:表示可以是任意类型 二 通配符在泛型类创建泛型对象中使用 1 代码 class gent<T> { publ

  • Java泛型的继承和实现操作示例

    本文实例讲述了Java泛型的继承和实现操作.分享给大家供大家参考,具体如下: 一 点睛 泛型类和泛型接口被定义后,是可以被继承和实现的. 二 泛型类的继承 1 代码 class A<E> { E t; } public class B<T,T1>extends A<T>{ public static void main(String[] args){ System.out.println("B test"); } } 2 运行 B test 3 说明

  • Java中方法名称和泛型相同的用法示例

    本文实例讲述了Java中方法名称和泛型相同的用法.分享给大家供大家参考,具体如下: 一 点睛 Java中,方法的名称可以用泛型替代. 二 实战 1 代码 public class SupGent { public class A<E> { E t; public A( E t ) { this.t = t; } public E E() { //采用了泛型E,碰巧方法名称也是E,只不过不要弄混淆,有点像宏替换 return t; } } public class B<E> exte

  • Java泛型与数据库应用实例详解

    本文实例讲述了Java泛型与数据库应用.分享给大家供大家参考,具体如下: 一 点睛 BaseDao定义了基本的数据库增删查改, 之后可以继承该泛型类,实现各自的增删查改,或者使用超类的增删查改,同时每个继承类还能增加自己的操作. 二 实战 1 BaseDao.java import java.lang.reflect.Field; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepared

  • Java定义泛型接口和类的方法实例分析

    本文实例讲述了Java定义泛型接口和类的方法.分享给大家供大家参考,具体如下: 一 点睛 所谓泛型:就是允许在定义类.接口指定类型形参,这个类型形参在将在声明变量.创建对象时确定(即传入实际的类型参数,也可称为类型实参). JDK1.5改写了集合框架中的全部接口和类,为这些接口.类增加了泛型支持,从而可以在声明集合变量.创建集合对象时传入类型实参. 二 实战 1 代码 // 定义Apple类时使用了泛型声明 public class Apple<T> { // 使用T类型形参定义实例变量 pr

  • Java泛型定义与用法入门示例

    本文实例讲述了Java泛型定义与用法.分享给大家供大家参考,具体如下: 一 引入泛型背景 Java集合不会知道它们需要用它来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要求具有很好的通用性.但这样做也带来两个问题: 集合对元素类型没有任何限制,这样可能引发一些问题:例如想创建一个只能保存Dog对象的集合,但程序也可以轻易地将Cat对象"丢"进去,所以可能引发异常. 由于把对象"丢进"集合时,集合丢失了对象的状态信息,集合只知道它盛装的是Objec

  • Java泛型变量如何添加约束

    有时,类或方法需要对类型变量加以约束.下面是一个典型的例子,我们要寻找数组中的最小元素: public class ArrayAlg { public static <T extends Comparable> T min(T[] array){ if (array == null || array.length == 0){ return null; } T smallest = array[0]; for (int i=0;i<array.length;i++){ if (small

  • Java泛型机制必要性及原理解析

    泛型程序设计(Generic Programming) "使用泛型机制编写的程序代码要比那些杂乱地使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性.泛型对于集合类尤其有用." 1.意义.必要性.重要性 泛型程序设计 意味着编写的代码可以被很多不同类型的对象所重用.例如,我们并不希望为聚集String和File对象分别设计不同的类.实际上,也不需要这样做,因为一个ArrayList类就可以聚集任何类型的对象.这是一个泛型程序设计的实例. 事实上,在Java增加泛

  • Java等待唤醒机制线程通信原理解析

    这篇文章主要介绍了Java等待唤醒机制线程通信原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同.比如:线程A用来生成包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个是生产,一个是消费,那么线程A与线程B之间就存在线程通信问题. 为什么要处理线程间通信: 多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个

  • java同步器AQS架构AbstractQueuedSynchronizer原理解析下

    目录 引导语 1.释放锁 1.1.释放排它锁release 1.2.释放共享锁releaseShared 2.条件队列的重要方法 2.1.入队列等待await 2.1.1.addConditionWaiter 2.1.2.unlinkCancelledWaiters 2.2.单个唤醒signal 2.3.全部唤醒signalAll 3.总结 引导语 AQS 的内容太多,所以我们分成了两个章节,没有看过 AQS 上半章节的同学可以回首看一下哈,上半章节里面说了很多锁的基本概念,基本属性,如何获得锁

  • 精通Java泛型的使用与原理

    目录 泛型之前 通过继承设计通用程序 泛型 Java泛型的实现原理 原始类型 突破泛型约束 泛型方法的类型推断 正确的运转 泛型相关问题 1.泛型类型引用传递问题 2.泛型类型变量不能是基本数据类型 3.运行时类型查询 4.泛型在静态方法和静态类中的问题 泛型相关面试题 1. Java中的泛型是什么 ? 使用泛型的好处是什么? 2.Java的泛型是如何工作的 ? 什么是类型擦除 ? 3. 什么是泛型中的限定通配符和非限定通配符 ? 4. List<? extends T>和List <?

  • Java反射机制概念、原理与用法总结

    本文实例讲述了Java反射机制概念.原理与用法.分享给大家供大家参考,具体如下: 反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 反射机制能做什么 反射机制主要提供了以下功能: ① 在运行时判断任意一个对象所属的类: ② 在运行时构造任意一个类的对象: ③ 在运行时判断任意一个类所具有的成员变量和方法: ④ 在运行时调用任意一个

  • Java泛型机制的程序演示详解

    本文为大家分享了Java泛型机制的程序演示具体代码,供大家参考,具体内容如下 package packA; import java.util.*; public class GenericDemo { public static void main(String[] args) { TreeSet<String> ts = new TreeSet<String>( new LenSort() ); //<String> 泛型 ts.add("hidwju&qu

  • Java流程控制顺序结构原理解析

    这篇文章主要介绍了Java流程控制顺序结构原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 流程控制的概念 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说,程序的流程对运行结果有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要通过控制语句的执行顺序来实现我们要完成的功能. 流程控制之顺序结构 根据代码的编写顺序,从上往下,依次执行. 顺序结构之流程图 ​ 需求 举例说明顺序结构的执行

  • Java方法覆盖重写实现原理解析

    这篇文章主要介绍了Java方法覆盖重写实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方法覆盖重写注意事项: 1.必须保证方法名相同,返回值也相同 @Override:写在方法前面,用来检测方法的覆盖重写是否有效,这个注解不是必要的,就算不写,方法覆盖重写符合要求也是正确的 2.子类方法的返回值必须[小于等于]父类方法的返回值 3.子类方法的修饰符必须[大于等于]父类方法的修饰符 继承关系中,父子类构造方法的访问特点: 1.子类构造

  • java instanceof操作符使用及原理解析

    这篇文章主要介绍了java instanceof操作符使用及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 a intanceof A:判断a是否是类A的的一个实例,返回值为boolean public class Person extends Object{} public class Student extends Person{} public class Graduate extends Person{} public clas

  • Java枚举类接口实例原理解析

    这篇文章主要介绍了Java枚举类接口实例原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 枚举类可以实现一个或多个接口.与普通类实现接口完全一样,枚举类实现接口时,需要实现该接口所包含的方法. 如果需要每个枚举值在调用同一个方法时呈现不同的行为,则可以让每个枚举值在{...}匿名块中实现自己的业务逻辑. public interface IGradeHandler { String getGrade(String studentName)

随机推荐