zoukankan      html  css  js  c++  java
  • 从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,并没有什么区别。

  • 相关阅读:
    C# 文件操作(读取文本/日志文件,读取文件列表,创建HTML,写入日志文件)
    网页布局与优化
    深度复制与浅度复制
    Silver 操作Cookie
    HTTP Method小结
    C# 主动发起请求代码
    震动放声音
    细数Objective-C中的回调机制
    iOS7隐藏状态栏 status Bar
    本地化UIImagePicker中的文字
  • 原文地址:https://www.cnblogs.com/LvJiaXuanBlogs/p/11131010.html
Copyright © 2011-2022 走看看