從C#到Java(泛型)


  之前沒做java的時候就一直聽說java的泛型是假泛型,但是一直沒有去了解過,最近做了java發現很多和C#泛型不同的地方,比如:

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

  what fuck?為什么這個會報錯?那我想return new T呢?

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

    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可以看出來這個問題的答案:

 

 

可以看到,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,並沒有什么區別。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM