靜態方法上的泛型

泛型也可以僅定義在靜態方法上,舉例而言,在 定義與使用泛型 中自定義過支援泛型的ArrayList,如果現在想寫個asArrayList方法,可指定不定長度引數,將之轉換為ArrayList,則可以如下:

package cc.openhome;

public class Util {
public static <T> ArrayList<T> asList(T... a) {
ArrayList<T> arrLt = new ArrayList<>();
for(T t : a) {
arrLt.add(t);
}
return arrLt;
}
}

想使用這個asList()方法,完整的泛型宣告語法如下:

ArrayList<String> arrLt = Util.<String>asList("B", "X", "A", "M", "F", "W", "O");

實際上,編譯器可以從asList()的引數,瞭解到型態參數T實際上是String型態,因此,可以簡化撰寫為:

ArrayList<String> arrLt = Util.asList("B", "X", "A", "M", "F", "W", "O");

某些方法宣告下,編譯器無法從引數推斷型態參數的實際型態,那就可能從其他管道來進行推斷。例如,你可能如下定義:

...
public class BeanUtil {
    public static <T> T getBean(Map<String, Object> data, String clzName)
                                   throws Exception {
        Class clz = Class.forName(clzName);
        ...略
        return (T) bean;  
    }
}

想使用這個程式片段中的getBean()方法,完整語法可以如下:

Student student = BeanUtil.<Student>getBean(data, "cc.openhome.Student");

就以上片段來說,其實編譯器可以從student的型態推斷,型態參數T應該是Student,因此可以簡化撰寫為:

Student student = BeanUtil.getBean(data, "cc.openhome.Student");

編譯器會自動推斷T代表的型態,就不用額外指定<Student>,完整語法是想在鏈狀操作時使用。例如:

String name = BeanUtil.<Student>getBean(
                     data, "cc.openhome.Student").getName();

在上例,如果沒有指定<Student>,那麼就無法呼叫傳回的Student物件getName()方法,因為編譯器會將getBean()傳回的物件型態當作Object處理,而Object上並不會有getName()方法,因而發生錯誤,這跟上面的UtilasList()可以比較一下:

Util.asList("B", "X", "A", "M", "F", "W", "O").get(10).toUpperCase();

這個語法不會發生錯誤,因為編譯器可以從asList()的引數,瞭解到型態參數T實際上是String型態,因而傳回型態會是ArrayList<String>,而呼叫get(10)會傳回String,因而最後可以呼叫toUpperCase()

編譯器的型態推斷是很方便的功能,實際上你也早用過型態推斷而得到方便性,在 陣列複製 中使用過java.util.ArrayscopyOf()方法,實際上你不用使用CAST語法,例如:

String[] words = {"A", "X", "B", "Y"};
String[] newWords = Arrays.copyOf(words, words.length * 2);

java.util.ArrayscopyOf()方法可以接受任何型態的陣列,是因為其宣告上使用了泛型:

public static <T> T[] copyOf(T[] original, int newLength)

因此,編譯器可以從引數得知型態參數實際型態,強大的類型推斷對需要宣告變數型態的語言來說,有助於語法的簡化,尤其對Java在JDK8引入Lambda之後,會更加方便,對Lambda語法的可讀性有極大的助益,這之後還會再看到介紹。

最新文章

  1. Web前端开发工程师养成计划【转载】
  2. inference和learning
  3. Ubuntu上安装和使用SSH,Xming+PuTTY在Windows下远程Linux主机使用图形界面的程序
  4. 双绞线线序+POE供电网线
  5. C# 三种实现抖屏的方式
  6. JS中 判断null
  7. Web App之一
  8. Pencil OJ 01 开发的准备
  9. 在LINQ中实现多条件联合主键LEFT JOIN
  10. 结队编程study
  11. css3动画小案例
  12. NIO FileChannel
  13. XML注入(XXE)
  14. 1、IT人思维之投资开篇 - IT人思维之投资
  15. 修改oracle的字符集操作方法
  16. 【做题】SDOI2017硬币游戏——方程&概念处理
  17. 70部MAYA灯光材质渲染教程合集
  18. zabbix系列之安全
  19. for each...in,for...in, for...of
  20. mysql 数据操作 单表查询 group by 介绍

热门文章

  1. POJ 2923 Relocation(状压DP+01背包)题解
  2. 解决QML Window 增加radius效果
  3. (CLR via C#学习笔记)线程基础
  4. javascript中back(-1)和go(-1)的区别
  5. Eclipse 常用快捷键和使用技巧
  6. Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
  7. UVA-10801 Lift Hopping (最短路)
  8. mysqli使用记录
  9. MarkdownPad2 在 Windows10 下 预览无法显示
  10. 从客户端中检测到有潜在危险的 Request.Form 值 方法