亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java泛型真的是雞肋嗎?

2019-11-06 06:58:25
字體:
來源:轉載
供稿:網友

學習java的同學注意了!??! 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:523047986  我們一起學Java!

今天遇到一個小問題,讓我感覺Java的泛型(因為背負了歷史的包袱導致的)有點雞肋啊。

我們經常會遇到要一些自定義的key-value字符串,比如:

"key1:1k;key2:2;key3:3"

通常編碼的時候會將它轉換為一個Map這樣方便操作,因為key和value的類型不一定(可能是int也可能是String等),于是我用Java寫了一個簡單的泛型方法:

復制代碼
@SupPRessWarnings("unchecked")    public static <K, V> Map<K, V> getMap(String source, String firstSplit, String secondSplit) {        Map<K, V> result = new HashMap<K, V>();        if (source.equals("")) {            return result;        }        String[] strings = source.split(firstSplit);        for (int i = 0; i < strings.length; i++) {            String[] tmp = strings[i].split(secondSplit);            if (tmp.length == 2) {                result.put((K) tmp[0], (V) tmp[1]);                // System.out.println("(K) tmp[0]:"+((K) tmp[0]).getClass());                // System.out.println("(V) tmp[1]:"+((V) tmp[1]).getClass());            }        }        return result;    }復制代碼

看上去貌似可以正常工作的,用上面的字符串舉例子,我應該希望得到的是Map<String, Integer>這樣一個結果。

String test = "key1:1k;key2:2;key:3";        Map<String, Integer> map = getMap(test, ";", ":");        for (Entry<String, Integer> entry : map.entrySet()) {            Integer value = entry.getValue();        }

上面的代碼編譯時完全沒問題的,但是一運行:

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integerat ossp.demo.generic.GenericDemo.main(GenericDemo.java:38)

報的是類型轉換錯誤,String不能轉換為Interger類型?但是明明entry.getValue()結果就是Interger類型啊,難道不是嗎?

 

一開始很疑惑,但稍微一想就明白了,哦!Java泛型用的是“擦除”法,完全是編譯期的,運行時已經沒有泛型參數的類型信息了,也就是說運行時所有的泛型參數都被替換成了Object(如果有泛型約束(.net是這么叫的)是不是就替換成上限類型?)所以上面的泛型方法其實就等價于:

復制代碼
public static Map<Object, Object> getMap(String source, String firstSplit, String secondSplit) {        Map<Object, Object> result = new HashMap<Object, Object>();        if (source.equals("")) {            return result;        }        String[] strings = source.split(firstSplit);        for (int i = 0; i < strings.length; i++) {            String[] tmp = strings[i].split(secondSplit);            if (tmp.length == 2) {                result.put((Object) tmp[0], (Object) tmp[1]);            }        }        return result;    }復制代碼

也就是說entry.getValue();返回的其實是一個Object對象的,它的類型應該是java.lang.String,于是我想那么這樣轉換一下應該可以了:

Integer value = Integer.valueOf(entry.getValue());

但是讓我郁悶的是仍然報之前的錯誤,鼠標點上去,智能提示看執行的應該是參數為int的重載反復,額,又繞回去了。

那怎么才能得到我想得到那個Integer的value呢???最后我發現這樣是可以的:

Integer value = Integer.valueOf(String.valueOf(entry.getValue()));

我靠!這太讓我無語了。不光如此我發現直接執行下面這行代碼也會報類型轉換錯誤:

System.out.println(entry.getValue().getClass());

既然entry.getValue()的類型是java.lang.String,為什么Map<String, Integer> map = getMap2(test, ";", ":");和Entry<Object, Integer> entry : map.entrySet()這兩行又都能編譯通過呢?想想還是萬惡的“類型擦除“的原因,我們先看看C#里的情況。

 Dictionary<string, int> dic1 = new Dictionary<string, int>(); Dictionary<string, double> dic2 = new Dictionary<string, double>(); Console.WriteLine(dic1); Console.WriteLine(dic2);

我們知道.NET泛型將每個類型參數理解為一個獨立的類型,所以上面dic1和dic2的類型是不一樣的:

但是在Java里因為“類型擦除“實際上Map<String,Interger>和Map<String,Double>的類型都是:java.util.HashMap

Map<String, Integer> map1 = new HashMap<String, Integer>();Map<String, Double> map2 = new HashMap<String, Double>();System.out.println(map1.getClass());System.out.println(map2.getClass());

這樣看來上面的代碼編譯通過是必須的,那么這智能提示有什么意義呢(編譯期的YY?)。

 

我們看看同樣的問題C#是怎么解決的。一開始我以為像Java那樣直接強制類型轉換就可以:

或者這樣:

這些都是不行的。但是只要運行運行時還有類型參數的信息,那么肯定是有辦法辦到的,.NET中庫中就有現成的這樣一個方法:Convert.ChangeType,于是我們可以寫出下面這個輔助泛型方法:

    static V GenericCast<U, V>(U obj)    {         return (V)Convert.ChangeType(obj, typeof(V));    }

于是乎為了解決我的問題,我可以寫這樣一個泛型方法了:

復制代碼
   static Dictionary<K, V> ToMap<K, V>(string source, string firstSplit, string secondSpilt)     {            Dictionary<K, V> result = new Dictionary<K, V>();            if (String.IsNullOrEmpty(source))            {                return result;            }            string[] info1 = source.Split(new string[] { firstSplit }, StringSplitOptions.RemoveEmptyEntries);            foreach (var item in info1)            {                string[] info2 = item.Split(new string[] { secondSpilt }, StringSplitOptions.RemoveEmptyEntries);                if (info2.Length == 2)                {                    result.Add(GenericCast<string, K>(info2[0]), GenericCast<string, V>(info2[1]));                }            }            return result;      } 復制代碼復制代碼
 string test = "key1:1.1;key2:2;key3:3"; Dictionary<string, double> map = ToMap<string, double>(test, ";", ":"); foreach (var item in map) {      Console.WriteLine(item.Key + ":" + item.Value); }復制代碼

 

并不是想黑Java,只是之前用C#的泛型用的比較爽,用Java的總感覺有點食之無味,棄之可惜。

學習Java的同學注意了?。?! 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:523047986  我們一起學Java!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
中文字幕欧美专区| 精品久久在线播放| 亚洲欧美999| 这里只有精品视频在线| 国内伊人久久久久久网站视频| 久久这里只有精品视频首页| 精品国产乱码久久久久久天美| 亚洲精品一区二区网址| 欧美洲成人男女午夜视频| 国产精品无码专区在线观看| 欧美一级黄色网| 91国内在线视频| 日韩电视剧在线观看免费网站| 超碰97人人做人人爱少妇| 久久精品成人欧美大片| 91精品国产乱码久久久久久久久| 亚洲精品97久久| 久热精品在线视频| 亚洲国产福利在线| 国产精品国产三级国产专播精品人| 日韩电影免费在线观看| 日韩欧美国产一区二区| 国产精品视频公开费视频| 欧美日韩国产成人高清视频| 国产精品一区二区久久| 国产精品羞羞答答| 亚洲午夜女主播在线直播| 91精品视频观看| 欧美色视频日本版| 日韩精品免费观看| 国产97在线视频| 黑人精品xxx一区一二区| 伊人久久久久久久久久久| 久久综合国产精品台湾中文娱乐网| 国产一区视频在线播放| 国产视频亚洲精品| 日韩精品福利网站| 国产精品小说在线| 欧美插天视频在线播放| 亚洲永久在线观看| 91九色国产社区在线观看| 精品视频在线播放| 国产精品久久精品| 国产91精品久久久| 色七七影院综合| 亚洲视频一区二区三区| 精品国产乱码久久久久酒店| 欧洲成人性视频| 最新亚洲国产精品| 成人免费看片视频| 亚洲片av在线| 欧美性xxxxx极品| 久久这里只有精品99| 国产精品91久久久| 欧美日韩日本国产| 黄色一区二区在线观看| 欧美激情视频在线免费观看 欧美视频免费一| 在线观看国产精品淫| 欧美性生交xxxxx久久久| 欧美日韩国产在线看| 国产精品一区二区三区免费视频| 亚洲欧美日韩高清| 国产成人精品一区二区三区| 韩国19禁主播vip福利视频| 亚洲xxxx做受欧美| 日韩av有码在线| 色妞色视频一区二区三区四区| 精品高清美女精品国产区| 国产精品户外野外| 一区二区三区视频观看| 亚洲国产免费av| 欧美亚洲国产精品| 91黄色8090| 日本成熟性欧美| 国产视频在线观看一区二区| 国产激情久久久久| 日韩欧美国产骚| 欧美性在线视频| 国产亚洲精品一区二区| 成人在线小视频| 国产精品视频久久| 欧美视频在线观看免费网址| 精品欧美国产一区二区三区| 亚洲精品欧美一区二区三区| 欧美电影院免费观看| 色妞一区二区三区| 欧美激情2020午夜免费观看| 国产精品久久久久久婷婷天堂| 国产精品久久久久久久久久东京| 亚洲天堂av综合网| 日韩精品久久久久| 97成人超碰免| 欧日韩不卡在线视频| 好吊成人免视频| 欧美极度另类性三渗透| 夜夜躁日日躁狠狠久久88av| 亚洲欧美另类在线观看| 色中色综合影院手机版在线观看| 一本久久综合亚洲鲁鲁| 日韩av123| 精品国产乱码久久久久久虫虫漫画| 亚洲在线一区二区| 最近2019中文字幕大全第二页| 日本一区二区在线免费播放| 日韩一级裸体免费视频| 日韩在线免费观看视频| 久久久91精品| 亚洲色图激情小说| 亚洲最大成人免费视频| 97久久精品国产| 亚洲精品视频免费在线观看| 91精品在线观看视频| 美女999久久久精品视频| 久久久国产视频| 久久免费在线观看| 姬川优奈aav一区二区| 亚洲午夜小视频| 日韩精品在线观| 亚洲欧美日韩精品久久亚洲区| 亚洲第一区第二区| 国产一区二区三区视频免费| 日韩av片永久免费网站| 18一19gay欧美视频网站| 清纯唯美日韩制服另类| 国产99久久精品一区二区永久免费| 国产成人精品免高潮费视频| 欧美疯狂性受xxxxx另类| 国产精品第一视频| 青草热久免费精品视频| 青青草原成人在线视频| 精品视频久久久久久久| 粗暴蹂躏中文一区二区三区| 亚洲毛片在线免费观看| 91国产美女视频| 欧美激情综合色| 91久久国产婷婷一区二区| 日韩中文在线观看| 欧美日韩亚洲一区二区三区| 国产日韩欧美综合| 久久久久久久国产| 久久国产精品久久久久| 欧美精品国产精品日韩精品| 日韩精品欧美国产精品忘忧草| 国产精品视频久久久久| 成人春色激情网| 亚洲日本中文字幕| www.亚洲男人天堂| 久青草国产97香蕉在线视频| 日韩在线视频网站| 日韩av免费网站| 91最新在线免费观看| 久久久久九九九九| 91在线播放国产| 久久色精品视频| 欧美日韩在线视频观看| 亚洲国产欧美在线成人app| 亚洲精品一区二区三区婷婷月| 日韩精品欧美国产精品忘忧草| 精品夜色国产国偷在线| 在线观看亚洲视频| 91国产高清在线| 欧美日韩国产一区二区| 亚洲精品视频在线观看视频| 色老头一区二区三区在线观看|