靜態方法上的泛型

泛型也可以僅定義在靜態方法上,舉例而言,在 定義與使用泛型 中自定義過支援泛型的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語法的可讀性有極大的助益,這之後還會再看到介紹。

java 静态方法上的泛型的更多相关文章

  1. 【Java心得总结三】Java泛型上——初识泛型

    一.函数参数与泛型比较 泛型(generics),从字面的意思理解就是泛化的类型,即参数化类型.泛型的作用是什么,这里与函数参数做一个比较: 无参数的函数: public int[] newIntAr ...

  2. 【Java学习笔记】泛型

    泛型: jdk1.5出现的安全机制 好处: 1.将运行时期的问题ClassCastException转到了编译时期. 2.避免了强制转换的麻烦. <>: 什么时候用? 当操作的引用数据类型 ...

  3. JAVA提高六:泛型

    在面向对象编程语言中,多态算是一种泛化机制.例如,你可以将方法的参数类型设置为基类,那么该方法就可以接受从这个基类中导出的任何类作为参数,这样的方法将会更具有通用性.此外,如果将方法参数声明为接口,将 ...

  4. Java Collections API和泛型

    Java Collections API和泛型 数据结构和算法 学会一门编程语言,你可以写出一些可以工作的代码用计算机来解决一些问题,然而想要优雅而高效的解决问题,就要学习数据结构和算法了.当然对数据 ...

  5. Java基础 -- 深入理解泛型

    一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 而泛型很好的解决了这个问题,这也是Java SE5的重大 ...

  6. JAVA基础--JAVA 集合框架(泛型、file类)16

    一.集合总结 集合:Collection体系.Map体系. Collection体系:单列集合的共性操作规则. List:列表,可以重复,有下标,拥有特有的迭代器ListIterator. Array ...

  7. JAVA基础--JAVA 集合框架(泛型、file类)

    一.集合总结 集合:Collection体系.Map体系. Collection体系:单列集合的共性操作规则. List:列表,可以重复,有下标,拥有特有的迭代器ListIterator. Array ...

  8. Day 8:方法上自定义泛型、类上、接口上、泛型的上下限

    泛型 泛型是jdk1.5使用的新特性  泛型的好处:   1. 将运行时的异常提前至了编译时    2. 避免了无谓的强制类型转换 泛型在集合中的常见应用:    ArrayList<Strin ...

  9. 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的

    数组和泛型容器有什么区别 要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance).逆变性(contravariance)和无关性(invariant). 若类A是类B的子类, ...

随机推荐

  1. 寻找List之和的最近素数

    Task : Given a List [] of n integers , find minimum mumber to be inserted in a list, so that sum of ...

  2. Docker:Err http://archive.ubuntu.com trusty InRelease & E: Unable to locate package [name] 问题

    参考: Docker containers can't resolve DNS on Ubuntu 14.04 Desktop Host Unable to locate package错误解决办法 ...

  3. UVa 1636 决斗

    https://vjudge.net/problem/UVA-1636 题意: 首先在手枪里随机装了一些子弹,然后抠了一枪,发现没有子弹.你希望下一枪也没有子弹,是应该直接再抠一枪还是随机转一下再抠. ...

  4. R中的路径设置

    软件的路径设置对于电脑的内存管理和自己的寻根究底十分重要.所以,合理的设置R中相关路径,能更加方便快捷的管理自己的相关文件,提高学习R语言的效率,建立自己的习惯体系. R中的路径设置主要有以下几个方面 ...

  5. BZOJ 3676 【APIO2014】 回文串

    题目链接:回文串 我终于也会回文自动机辣! 其实吗……我觉得回文自动机(听说这玩意儿叫\(PAM\))还是比较\(simple\)的……至少比\(SAM\)友善多了…… 所谓回文自动机,每个节点就代表 ...

  6. BZOJ 3529 【SDOI2014】 数表

    题目链接:数表 我们一起来膜PoPoQQQ大爷的题解吧Orz 首先我们来考虑没有\(a\)的限制该怎么做.显然交换\(n\),\(m\)答案不变,所以后面默认\(n \le m\). 我们定义两个函数 ...

  7. 2016"百度之星" - 资格赛(Astar Round1) A 逆元

    Problem A  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 65536/65536 K (Java/Others) Problem ...

  8. 自行申请德国的VAT号码?

    我在香港/大陆地区,是否可以自行申请德国的VAT号码? 德国联邦税务局按照不同国家申请人划分成不同申请办公室,以下为德国联邦税务局负责中国境内申请人的办公室地址及联络方式: FINANZAMT BER ...

  9. 导出csv文件,导出axlsx文件。gem 'Axlsx-Rails' (470🌟);导入csv文件。

    汇出 CSV 档案 需求:后台可以汇出报名资料 有时候后台功能做再多,也不如 Microsoft Excel 或 Apple Numbers 试算表软件提供的分析功能,这时候如果有汇出功能,就可以很方 ...

  10. HTML5 Canvas 代码检测浏览器是否支持

    在创建HTML5 Canvas元素之前,首先要检测浏览器是否能够拿支持他,如果不支持,就要用文字或图片替代,检测代码如下所示. <!DOCTYPE html> <html> & ...