Java核心技术(五) —— 泛型程序设计(2)

本文延续上文,针对泛型程序设计,从以下方面进行讲解:

  • 为何使用泛型程序设计
  • 定义简单的泛型类
  • 泛型方法
  • 类型变量的限定
  • 泛型代码和虚拟机
  • 约束与局限性
  • 泛型类型的继承规则
  • 通配符类型
  • 反射和泛型

4、泛型代码和虚拟机

这里内容比较多且杂,我们先概括几个主要思想:

  • 虚拟机中没有泛型,只有普通的类和方法
  • 所有的类型参数都用他们的限定类型转换
  • 桥方法被合成来保持多态
  • 为保持类型安全性,必要时插入强制类型转换

(1)当定义一个泛型类型时,系统会自动提供一个相应的原始类型。原始类型的名字就是删去类型参数后的泛型类型名。擦除类型变量,并替换为限定类型。

(2)当程序调用泛型方法时,如果擦除返回类型,编译器就会插入相对应的强制类型转换。

5、约束与局限性

下面深入探讨使用Java泛型时需要考虑的一些限制,大多数限制都是由类型擦除引起的

5.1 不能用基本类型实例化类型参数

不能用类型参数代替基本类型,即没有Pair<double>只有Pair<Double>。这是因为类型擦除以后,Pair类含有Object类型的域,而Object不能存储double值。

5.2 运行时类型查询只适用于原始类型

虚拟机中的对象总有一个特定的非泛型类型,因此,所有的类型查询只产生原始类型。

5.3 不能创建参数化类型的数组

5.4 Varargs警告

5.5 不能实例化类型变量

不能使用像new T(···),new T[···]或者T.class这样的表达式中的类型变量。

5.6 泛型类的静态上下文中类型变量无效

5.7 不能抛出或捕获泛型类的实例

5.8 注意擦除后的冲突

6、泛型类型的继承规则

简单说来,就是无论S与T有什么联系,通常Pair<S>Pair<T>没有什么联系。例如Manager类是Employee类的子类,但Pair<Employee>Pair<Manager>并没有什么关系。

7、通配符类型

固定的泛型类型系统使用起来很不爽,因此出现了通配符类型。例如

Pair<? extends Employee>

表示任何泛型Pair类型,它的类型参数是Employee的子类,如Pair<Manager>而不会是Pair<String>

7.1 通配符的超类型限定

通配符限定与类型变量限定十分相似,但还有一个附加功能,即可以指定一个超类型限定。例如

? super Manager

这个通配符限制为Manager的所有超类型。

7.2 无限定通配符

无限定通配符使用方式,如Pair<?>

7.3 通配符捕获

通配符捕获只有在有许多限制的情况下才是合法的,编译器必须能够确信通配符表达的时单个的、确定的类型。

下面,我们用一个例程来回顾前面讲述的概念们

package pair3;

public class PairTest3
{
   public static void main(String[] args)
   {
      Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
      Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15);
      Pair<Manager> buddies = new Pair<>(ceo, cfo);
      printBuddies(buddies);

      ceo.setBonus(1000000);
      cfo.setBonus(500000);
      Manager[] managers = { ceo, cfo };

      Pair<Employee> result = new Pair<>();
      minmaxBonus(managers, result);
      System.out.println("first: " + result.getFirst().getName()
         + ", second: " + result.getSecond().getName());
      maxminBonus(managers, result);
      System.out.println("first: " + result.getFirst().getName()
         + ", second: " + result.getSecond().getName());
   }

   public static void printBuddies(Pair<? extends Employee> p)
   {
      Employee first = p.getFirst();
      Employee second = p.getSecond();
      System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
   }

   public static void minmaxBonus(Manager[] a, Pair<? super Manager> result)
   {
      if (a == null || a.length == 0) return;
      Manager min = a[0];
      Manager max = a[0];
      for (int i = 1; i < a.length; i++)
      {
         if (min.getBonus() > a[i].getBonus()) min = a[i];
         if (max.getBonus() < a[i].getBonus()) max = a[i];
      }
      result.setFirst(min);
      result.setSecond(max);
   }

   public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
   {
      minmaxBonus(a, result);
      PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
   }
}

class PairAlg
{
   public static boolean hasNulls(Pair<?> p)
   {
      return p.getFirst() == null || p.getSecond() == null;
   }

   public static void swap(Pair<?> p) { swapHelper(p); }

   public static <T> void swapHelper(Pair<T> p)
   {
      T t = p.getFirst();
      p.setFirst(p.getSecond());
      p.setSecond(t);
   }
}

时间: 2024-09-29 03:19:19

Java核心技术(五) —— 泛型程序设计(2)的相关文章

Java核心技术(五) —— 泛型程序设计(1)

本文主要针对泛型程序设计,从以下方面进行讲解: 为何使用泛型程序设计 定义简单的泛型类 泛型方法 类型变量的限定 泛型代码和虚拟机 约束与局限性 泛型类型的继承规则 通配符类型 反射和泛型 泛型程序设计,意味着编写的代码可以被很多不同类型的对象所重用. 1.泛型类 一个泛型类就是具有一个或多个类型变量的类,如定义一个Pair类 其中,Pair类引入了一个类型变量T,一般用比较短的大写形式来书写.实际上泛型类可以有多个类型变量,如上述程序中可以定义第一个域和第二个域具有不同的类型 之后,只要用具体

Java核心技术-泛型程序设计

使用泛型机制编写的代码要比那些杂乱地使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读性. 泛型对于集合类尤其有用 1 为什么要使用反省程序设计 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 1.1 类型参数的好处 在Java中增加泛型类之前,泛型程序设计是用继承实现的.ArrayList类只维护一个Object引用的数组: private class ArraryList { private Object[] elementData; ... public

Java核心技术卷一 6. java泛型程序设计

泛型程序设计 泛型程序设计:编写的代码可以被很多不同类型的对象所重用. 类型参数:使用<String>,后者可以省略,因为可以从变量的类型推断得出.类型参数让程序更具更好的可读性和安全性. 通配符类型:很抽象,让库的构建者编写出尽可能灵活的方法. 定义简单泛型类 泛型类就是具有一个或多个类型变量的类. //引用类型变量 T ,可以有多个类型变量,public class Pair<T, U>{...} public class Pair<T> { //类定义的类型变量制

java核心技术学习笔记之一程序设计概述

Java 核心技术之一程序设计概述 一.   Java语言的特点 简单行 :取经于C++,排除了C++不常用的指针.结构等,增加垃圾回收. 面向对象:与C++不同是单继承,但是可以继承多接口.完全面向对象的语言: 网络技能:Socket,FTP,Http,URL编程简单: 健壮性:避免指针错误使用: 安全性:构建防病毒防篡改系统: 体系结构中立:字节码: 可移植性: 解释性:可以解释任何移植了的字节码: 高性能: 多线程 动态性: 二.   Internet 和 Java Applet 在网页中

Java基础语法&lt;十二&gt; 泛型程序设计

1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element (在集合中使用,因为集合中存放的是元素) T – Type(Java 类)(需要时还可以用临近的字母U和S)表示任意类型  S.U.V – 2nd.3rd.4th types K – Key(键) V – Value(值) N – Number(数值类型) ? – 表示不确定的java类型(无限制通配

Java核心技术 卷1 读书笔记 (3 Java基本程序设计结构)

3.3 数据类型 Java是强类型语言,必须为每一个变量声明一种类型. 3.3.1 整型 Java 提供四种整型 int 4字节 short 2字节 long 8字节 byte 1字节 长整型(long)数值有一个后缀L(例如40000000000L),十六进制数值有一个前缀0x(例如0xCAFE),八进制数值有一个前缀0(例如010). 3.3.2 浮点型 Java提供两种浮点类型 float 4字节 double 8字节 float类型的数值有一个后缀F(例如3.42F),没有后缀F的浮点数

201671010128 2017-10-30《Java程序设计》之泛型程序设计

一.基本概念 泛型也被称为参数化类型(parameterized type),就是在定义类.接口和方法时,通过类型参数指示将要处理的对象类型.(如ArrayList类) 泛型程序设计(Generic programming)意味着编写代码可以被很多不同类型的对象所重用. 一个泛型类(generic class)就是具有一个或多个类型变量的类,即创建用类型作为参数的类. 二.一些特性 泛型类可以有多个类型变量.例如:public class Pair<T, U> { - } 类定义中的类型变量用

1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\

. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环境是一个包含了不同的类和程序的单一进程.线程可以被称为轻量级进程.线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源. 2. 多线程编程的好处是什么? 在多线程程序中,多个线程被并发的执行以提高程序的效率,CPU不会因为某个线程需要等待资源而进入空闲状态. 3. 用户线程和守护线程有什么区别? 当我们在Java

Java核心技术第三章----Java的基本程序设计结构重难点总结

最近在看Java核心技术这本书,这里对第三章个人认为的重难点做一个总结.方便以后回顾,个人能力有限,本人菜鸟,大神勿喷,请大家多多指教. 一.位运算符 指定 A = 66(0100 0010); B = 22 (0001 0110)(这里为了简化说明支取一个字节即8位来运算) 位运算符比一般的算术运算符速度要快,而且可以实现一些算术运算符不能实现的功能.如果要开发高效率程序,位运算符是必不可少的.位运算符用来对二进制位进行操作,包括:按位与(&).按位或(|).按位异或(^).按位取反(~).按