从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,并没有什么区别。

转载于:https://www.cnblogs.com/LvJiaXuanBlogs/p/11131010.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值