从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

相关文章
相关标签/搜索