zoukankan      html  css  js  c++  java
  • 《Java核心技术》第八章读书笔记(泛型)

    第八章 泛型程序设计

    泛型方法

    class ArrayAlg{
    	public static <T> T getMiddle(T... a){
    		return a[a.length / 2]
    	}
    }
    

    当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型。类型变量放在修饰符的后面,返回类型的前面。

    String middle = ArrayAlg.<String>getMiddle("J","k","L")
    

    类型变量的限定

    public static <T extends Comparable> T func(T[] a){...}
    

    这个泛型方法规定了 T 必须实现 Comparable (Comparable本身也是一个泛型类型)接口。此方法只能被实现了Comparable接口的类(如String,localDate)的数组调用。否则会编译报错。

    一个类型变量或通配符可以有多个限定

    T extends Comparable & Serializable
    

    翻译泛型方法

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

    约束与局限性

    • 不能有基本类型实例化类型参数

      没有Pair<double>,只有Pair<Double>
      
    • 运行时类型查询只适用于原始类型

      if (a instanceof Pair<String>)  // Error
      Pair<String> p = (Pair<String>) a // Warning ---can only test that a is a Pair
      
      同样的道理,getClass总是返回原始类型
      Pair<String> stringPair = .....
      Pair<Employee> employeePair = ...
      if (StringPair.getClass()==employeePair.getClass()) 
      结果为true,因为两次调用getClass豆浆返回Pair.class
      
    • 不能创建参数化类型的数组

      因为对于泛型类型,擦除会使类型参数无效。能够通过数组存储检查,但是会导致一个类型错误。

      Pair<String> table = new Pair<String>[10] // Error
      
    • 不能实例化类型变量

      public Pair() {
      	first = new T();
      	second = new T();
      }  // error
      

      类型擦除会将T改变成Object,而且本意不希望调用new Object。

    • 不能构造泛型数组

      public static <T extends Comparable> T[] minmax(T[] a){T[] mm = new T[2]}
      // Error
      当类型擦除时,Object[]引用赋给Comparable[]时,会发生ClassCastException
      
    • 泛型类的静态上下文中类型变量无效

      public class Singleton<T>{
      	private static T singleInstance // Error
      	public static T getSingleInstance // error
      	{
      		if (singleInstance == null) {
      			return singleInstance
      		}
      	}
      }
      

      类型擦除后,只有一个Singleton类,只包含一个singleInstance域,因此禁止使用带有类型变量的静态域和方法。

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

      public class Problem<T> extends Exception {}  // Error
      catch中不能使用类型变量。
      

    通配符类型

    如果要编写一个答应雇员的方法:

    public static void printBuddies(Pair<Employee> p){}
    由于Pair<Employee>和Pair<Manager>没有什么联系,所以并不能将Pair<manager>传递
    使用通配符类型
    public static void printBuddies(Pair<? extends Employee> p){}
    
    • 无限定通配符

      Pair<?> 和 Pair有很大不同
      Pair<?>有?get 和 void set方法
      get方法返回值只能赋值给一个Object,set方法不能被调用。
      两者本质区别是Pair<?> 可以用任意Object对象调用原始Pair类的setObject方法
      
  • 相关阅读:
    [转] DataSet的的几种遍历
    [转] C#实现在Sql Server中存储和读取Word文件 (Not Correct Modified)
    C# 在根据窗体中的表格数据生成word文档时出错
    【剑指offer】堆栈推弹出序列
    kettle于javascript步骤错误处理
    【算法导论】堆排序
    malloc,free简单的实现
    Lichee (六) 优化配置的微内核
    EJBCA于Linux安装在
    【C++】智能指针auto_ptr简单的实现
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/13909347.html
Copyright © 2011-2022 走看看