從C#到Java(泛型)

  以前沒作java的時候就一直據說java的泛型是假泛型,可是一直沒有去了解過,最近作了java發現不少和C#泛型不一樣的地方,好比:java

T t = new T(); //這段代碼在C#中是很正常的一段代碼,可是在我寫java的時候發現報錯了

  what fuck?爲何這個會報錯?那我想return new T呢?jvm

  後來在網上找到了答案:Java的泛型在編譯的時候會使用「類型擦除」來實現泛型,也就是說編譯後的T會變成Object:spa

    public class Class1<K,V>
    {
        private Dictionary<K, V> keyValuePairs = new Dictionary<K, V>();


        public V Get(K k)
        {
            return keyValuePairs.GetValueOrDefault(k);
        }

        public void Set(K k,V v)
        {
            keyValuePairs.Add(k, v);
        }
    }

這段代碼,java編譯後的字節碼和C#編譯後的IL能夠看出來這個問題的答案:code

 

 

能夠看到,IL是的TKey是在運行時確切的包含了TKey TValue的信息的,CLR會根據運行時的不一樣狀態生成不一樣的類型。而Java是直接將泛型轉換成了Object。這就很操蛋了,那這段代碼在Java中怎麼實現呢:對象

public class Cache<TKey, TValue>
{
    public static TValue Instance;
}

public class Factory
{
    public static string Create<TKey>()
    {
        if (Cache<TKey, string>.Instance == null)
        {
            Cache<TKey, string>.Instance = // some expensive computation
        }

        return Cache<TKey, string>.Instance;
    }
}

TKey在運行時類型就已經被擦除了,假設這裏的字典/hashmap是一個<int,object>類型的,這段代碼在JVM平臺上建立的應該是一個hashmap對象,而且不會區分<int,object><int,string>,由於對於jvm來講hashmap<int,object>,hashmap<int,string>都是hashmap,並無什麼區別。blog

相關文章
相關標籤/搜索