1. 程式人生 > >我們真的瞭解泛型嗎?--從一個不菜的泛型菜問題中發現的問題

我們真的瞭解泛型嗎?--從一個不菜的泛型菜問題中發現的問題

二、困惑-不菜的泛型菜問題

三、突破-VectortoArray()方法

四、結局-掀起你的蓋頭來

五、小結

六、附件

我以為對泛型已經很熟悉了。如果別人問泛型是什麼?我會舉一個簡單的例子,比如

Vector<String> sv = new Vector<String>();

就用到了泛型,這樣寫程式碼的一個明顯的好處就是以後不用型別檢查。比如

String s = sv.get(i);

一點

for (Iterator<String> it = sv.iterator(); it.hasNext(); ) {

s = it.next();

}

另外jsdk還提供了ArraysCollections兩個類,其中包含了大量運算元組和Collection的方法。總之java中使用泛型很方便也很簡單。

Java Tutorial中介紹了java泛型的很多好處,其中印象最深的是這句

Historically, collections frameworks have been quite complex...

We believe that the Java Collections Framework breaks with this tradition.

今天我才明白JavaTutorial介紹的是Collections Framework

不是真正的泛型。Java使用泛型實現了Collections Framework,並封裝起來,我們所能看到的僅僅是冰山一角。

這得從我前天在csdn看到的一個問題()說起。樓主看到一條這樣的語句,不知道是什麼意思。

public static <K,V> Map<K,V> newHashMap()

我也覺得很奇怪。當時第一放映,這只是個語法結構的描述,不是真正意義的語句。在真正語句裡<K, V>應該用具體的類來代替。因為不知道出處,為了證明,只好自己寫程式碼。

首先,根據我的思路,我寫了一個static方法,

public static <

String, Integer> Map<String, Integer> newHashMap1() {

HashMap<String, Integer> map = new HashMap<String, Integer>();

return map;

}

編譯通過。但還沒來得及高興,發現問題了。當我在其中加入這兩條語句時,

symbol: method valueOf(int)

map.put("1", Integer.valueOf(1));

卻無法編譯,提示如下資訊:

TestGenericSyntax.java:10: cannot find symbol

其中symbol指的是map.put("1", Integer.valueOf(1))。這怎麼可能?我又查了API Spec,沒錯。在別的地方插入這條語句也沒錯,單單是在這裡不行。

於是,興趣來了。又做了一些測試(見附件)。最後,一個令我非常吃驚的發現。

public static <K, V> Map<K, V> newHashMap4() {

HashMap<K, V> map = new HashMap<K, V>();

return map;

}

居然編譯通過。但令人不解的是,public static Map<K, V> newHashMap5()卻不能通過編譯。

當時手頭有別的事,沒有時間深究,只把我做的測試和疑問回覆過去了。一心等待樓主寫明出處貼,令我失望的是帖子沉的很深了,樓主始終沒漂上來。

沒想到今天一個關於泛型的帖子()使我找到了突破口。回覆了的問題,我突然發現API Spec中關於vector.oArray方法的宣告是這樣的,

public <T> T[] toArray(T[] a)

這個<T>是什麼?以前沒認真考慮,但今天我注意了,這不是那個<K, V>嗎?接著我又想起泛型的始祖,C++中的Template(使用Collections Framework太順手,把這岔兒給忘了)。於是我就想到了一個問題,我們知道

Vector<Integer> vi = new Vector<Integer>();

建立了一個儲存IntegerVector,而

Vector<String> vs = new Vector<String>();

又建立了一個儲存StringVector。那麼,這種功能,在Vector類的內部是怎麼實現的?回到前面的問題,

public <K, V> Map<K, V> newHashMap()

我斷定前面的<K, V>是對Map<K, V>中的<K, V>的型別宣告,或者準確的說是泛化。沒有原因,我一下想到了繼承,於是,又寫了兩個類,

class A {

public <K, V> Map<K, V> newHashMap() {

HashMap<K, V> map = new HashMap<K, V>();

return map;

}

}

class B extends A{

public Map<Integer, String> newHashMap() {

HashMap<Integer, String> map = new HashMap<Integer, String> ();

map.put(1, "A");

map.put(2, "B");

return map;

}

}

天總算亮了。

四、結局-掀起你的蓋頭來

到了這裡,其實問題也就明白了,看下面的程式碼,

A[] aa = new A[2];

aa[0] = new B();

aa[1] = new C(); // C也是繼承自A,見附件

for (int i=0; i<aa.length; i++) {

Map map = aa[i].newHashMap();

Set keyset = map.keySet();

for (Iterator it = keyset.iterator(); it.hasNext();) {

Object k = it.next();

Object v = map.get(k);

System.out.println(k + " " + v);

}

}

再看這裡,

class D extends A {

public Map<S, T> newHashMap() {

HashMap<S, T> map = new HashMap<S, T> ();

S s = new S();

T t = new T();

map.put(s, t);

return map;

}

}

class S extends JLabel{}

class T extends Component{}

如果你在設計類庫時聲明瞭class D,那麼在該類後續的使用中,開發人員可以擁有很大的自由度。這種功能是不是很強大?

還是時間的原因,不能再深究下去了,需要掌握的東西還很多,一下子不能扎得太深。再說,老婆也不會允許我掀別人的蓋頭。^_^

好吧,就此別過,後會有期。

五、小結

其實該說的都說了,沒什麼可總結的。留待大家討論吧。

六、附件

1) 測試1

// TestGenericSyntax.java

import java.util.*;

import java.lang.reflect.*;

public class TestGenericSyntax {

static String s = "Hello";

static Integer I = 0;

//static HashMap<s, I> hMap;

// 這也能過?

public static <s, I> Map<String, Integer> newHashMap() {

HashMap<String, Integer> map =

相關推薦

我們真的瞭解一個問題發現的問題

二、困惑-不菜的泛型菜問題 三、突破-Vector的toArray()方法 四、結局-掀起你的蓋頭來 五、小結 六、附件 我以為對泛型已經很熟悉了。如果別人問泛型是什麼?我會舉一個簡單的例子,比如 Vector<String> sv = new

蘋果新的編程語言 Swift 語言進階(二)基本數據類

保持 popu 多條語句 常量 num access 對象 程序 進制 一 、 常量和變量 Swift語言 對常量和變量的聲明進行了明白的區分 Swift語言的常量類型比C 語言的co

蘋果新的編程語言 Swift 語言進階(十三)檢查與類嵌套

兩個類 nes left p s 查詢 text edi host letter 一 類型檢查 1、 類型檢查操作符 類型檢查用來檢查或轉換一個實例的類型到另外的類型的一種方式。 在Swift中,類型檢查使用is和as操作符來實現。

我們有必要花時間瞭解spring boot

spring已經足夠好了 現在來看,spring框架真的太好了,任何一個java開發用過之後都會像上癮一樣,愛不釋手。會在遇到新問題的時候,或者找到某一個方法的時候,都會去看一下spring是不是已經有同類型的支援了。 如果有的話,我會毅然決然的選擇sp

校園網路安全CTF 第一題 和 你瞭解

第一題: 需要先找到相應頭(REsponse header中的tips)   <?php$flag = "***";if (isset($_GET['repo']))//檢測變數是否設定 { if (strcmp($_GET['repo'], $flag) == 0) //比較兩個

我們要了解我們國家常識一箇中國人必須知道

十二生肖】子鼠、丑牛、寅虎、卯兔、辰龍、巳蛇、午馬、未羊、申猴、酉雞、戌狗、亥豬2.【十大名茶】西湖龍井(浙江杭州西湖區)、碧螺春(江蘇吳縣太湖的洞庭山碧螺峰)、信陽毛尖(河南信陽車雲山)、君山銀針(湖南嶽陽君山)、六安瓜片(安徽六安和金寨兩縣的齊雲山)、黃山毛峰(安徽歙縣黃山)、祁門紅茶(安徽祁門

警察智力訓練藍橋杯歷年java題(java遞迴實現eval演算法)

匪警請撥110,即使手機欠費也可撥通!    為了保障社會秩序,保護人民群眾生命財產安全,警察叔叔需要與罪犯鬥智鬥勇,因而需要經常性地進行體力訓練和智力訓練!    某批警察叔叔正在進行智力訓練:    1 23 4 5 6 7 8 9 = 110;    請看上邊

拉丁方塊填數字藍橋杯國賽歷年

方塊填數  “數獨”是當下炙手可熱的智力遊戲。一般認為它的起源是“拉丁方塊”,是大數學家尤拉於1783年發明的。 如圖[1.jpg]所示:6x6的小格被分為6個部分(圖中用不同的顏色區分),每個部分含有6個小格(以下也稱為分組)。     開始的時候,某些小格中已經填寫了字母

通過例子學習ABAP(四)INSERT語句對於三種類的內表不同效果

(1)  通過索引插入行: INSERT LINE INTO ITAB INDEX IDX. (2)一般性的插入單行:INSERT [LINE INTO | INITIAL LINE INTO ] TABLE ITAB. 語句中增加了TABLE關鍵字,對於不同型別的內表,其意

也談為什麼我們重視Office開發看孟巖說有感

  看到孟巖兄的文章《》。根據我在應用行業的這麼多年的經驗,有一些想法,拿出來大家分享一下。 孟巖將問題的重點歸咎到國人對VB的輕視甚至鄙視的態度上,我認為不是很符合實際。在孟巖的部落格中,很多人對VB的作用產生懷疑。事實上,在一點上我是認同孟巖的想法的。雖然我對Delphi

python 物件的魔力、封裝和繼承

簡單介紹下這幾個名詞的意思。 多型(Polymorphism):意味著可以對不同類的物件使用相同的操作。 封裝(Encapsulation): 即對外部世界隱藏物件的工作細節。 繼承(Inheritance): 以通用的類為基礎建立專門的類物件。  一、多型     多型

敢為的性格鍛鍊大智慧大境界

談到敢為型性格--也許敢為性是自己性格中最缺乏的因子,“追求完美主義”的個性,導致自己做事情總是“謹小慎微”幾乎成了自己的毛病--一直在努力克服。行動上,不是說服自己之後立即行動,愣頭青一樣直線行走,就是藉助或者利用自己的“衝動”去採取行動。 敢不敢為--其實行動的本質起點依

kafka-kafka API(java版本)

spring mvc+my batis dubbo+zookeerper kafka restful redis分布式緩存 Apache Kafka包含新的Java客戶端,這些新的的客戶端將取代現存的Scala客戶端,但是為了兼容性,它們仍將存在一段時間。可以通過一些單獨的jar包調用這些客

Android加入新的視頻格式媒體庫掃描

日期 ams bsp net gif nload static class mar 需求:在mediaprovider數據庫中加入.mov後綴格式的視頻文件 能夠使用工具MediaInfo_GUI_0.7.67_Windows.3243836749.exe 查看mov文

老男孩教育每日一題2017-05-15-說說你在vi/vim常用的命令或快捷鍵

vi-vim編輯器 linux編輯器 每日一題 1.題目老男孩教育每日一題-2017-05-15-說說你在vi/vim中常用的命令或快捷鍵2.參考答案01:學會在vim中查詢幫助:help 或:h即可 :help G :help :wq02.vi/vim 使用最基本方法第一個裏程碑-使用vi打開o

ps技術批量給圖片加水印

photos strong http jpg 記錄 介紹 可見 出現 同一文件   在日常的辦公過程中,對於一些比較重要的文件的掃描件需要特殊處理,這時我們就需要給它們加上水印,保證它們的用途唯一,而這些掃描件很多,不可能一一給他們加水印,所以為提高工作效率,我們就可以使用

構建之法敏捷流程

uml 同時 那不 結束 出現問題 成員 模式 編寫 自我管理 最近為了完成java設計模式和uml的大作業算是花了不少時間來動腦理解和動手編寫代碼,也開始發現代碼的神奇和美妙,java竟然可以開發簡單的小遊戲,而且代碼並不向想象中那樣難以理解,其中的規律似乎很神奇。帶

鳥的mongoDB學習(六)MongoDB 索引

val drop -m 單位 處理 數列 track 掃描 大量 MongoDB 索引 ps:大概有半個月木有更新了,因為前一階段的出差和這幾天突然來的項目。導致上網時間急劇降低,實在是sorry,以後預計會好一點。 索引通常可以極大的提高查詢的效率。假設沒有

Prim算法:最小生成樹貪心算法的實現

http lin eai article log jre details otn 最小生成樹 算法圖解: http://baike.baidu.com/link?url=hGNkWIOLRJ_LDWMJRECxCPKUw7pI3s8AH5kj-944RwgeBSa9hGpT

debugnull Pointer Exception--一步步查找(2)

image party 添加 -- 空指針異常 pointer entity oca except 添加PartyLocationRepository後,再次在Ubuntu中編譯項目,再次報空指針異常。 直接在createDto處打斷點,然後debug每個表達式的值,找出