java 核心技术 卷 1 里面泛型一章中“泛型类的静态上下文中类型变量无效”这一节不能理解 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cmuler
V2EX    问与答

java 核心技术 卷 1 里面泛型一章中“泛型类的静态上下文中类型变量无效”这一节不能理解

  •  
  •   cmuler 2016-02-24 09:15:31 +08:00 3437 次点击
    这是一个创建于 3597 天前的主题,其中的信息可能已经有所发展或是发生改变。

    书里面这么写的:

    public class Singleton<T> { private static T singleInstance //ERROR private static T getSingleInstance() //ERROR { if(singleInstance == null) return singleInstance; } } 

    类型擦除后,只剩下 Singleton 类,它只包含一个 singleInstance 域。因此,禁止使用带有类型变量的静态域和方法。

    不太理解什么意思,为什么跟类型擦除有关系?请高手指点一下

    9 条回复    2016-02-24 13:58:41 +08:00
    ipeony
        1
    ipeony  
       2016-02-24 10:09:10 +08:00   1
    初始化顺序问题吧
    fwrq41251
        2
    fwrq41251  
       2016-02-24 10:12:59 +08:00   1
    泛型类上的泛型类型在实例化时确定。
    比如:
    Singleton<String> singletOnForString= new Singleton();
    Singleton<Boolean> singletOnForBoolean= new Singleton();
    而静态成员是被该类的所有对象共享的,显然你的泛型类型不能应用到静态成员上。
    sadwxds
        3
    sadwxds  
       2016-02-24 10:17:47 +08:00   1
    我是这么想的,如果你的泛型能够用在静态的属性或方法中。
    那么你在
    A 处 new Singleton<Integer>;
    B 处 new Singleton<YouClass>;
    那么当你调用 Singleton.getSingleInstance();
    你知道你将要返回的是什么样的类型结果吗?
    yrom
        4
    yrom  
       2016-02-24 10:26:22 +08:00   1
    类( Class )的类型参数( Type Parameters )只存在于类的实例的方法域和成员变量域。换句话说,必须实例化你这个类( Singleton )才知道那个类型参数“ T ”是什么鬼。 再比如, new Singleton<String>() , 这个时候"T"就是 String 。不知道明白了没。。
    SoloCompany
        5
    SoloCompany  
       2016-02-24 10:47:36 +08:00   1
    看你怎么理解, static 不能使用模板类型可以说和类型擦除有关也可以说无关
    具体到 java 泛型里面主要在于模板类型 T 的作用范围,本身规定就只是成员(变量以及方法)
    静态变量的作用范围完全不一样,所以不能使用模板类型
    从这一点上来说,可以说和类型擦除不一定相关

    但如果考虑到实现机制的话,就有可能相关,泛型有一种实现机制就是生成模板衍生类
    比如你举的这个例子 Singleton<T> 对应的是一个独立的衍生类 Singleton_T
    如果静态变量也复制一份的话,那么静态方法 /变量就可以使用模板类型
    就是说 Singleton<A>.singleInstance 和 Singleton<B>.singleInstnce 可以不一样(被复制)

    Java 的泛型机制是类型擦除机制,无论怎么实现都不可能有复制的静态变量,所以任意静态元素都不可以使用类定义的模板类型,因为他们之间毫无关系。你这么理解,静态变量以及方法和方法和他们所依附( enclosing )的类之间是完全没有关系的,他们只是简单的被放在一起而已
    SoloCompany
        6
    SoloCompany  
       2016-02-24 10:50:45 +08:00
    我觉得 Kotlin 把 static 关键字去除了是一个比较明智的选择
    因为 static 的确是不太 OO 的,而且会造成有些概念上的混淆
    用 package function 以及 compainion objet 来代替还是挺适合的
    cmuler
        7
    cmuler  
    OP
       2016-02-24 11:51:47 +08:00
    @SoloCompany 用模板类来实现泛型应该是 c#的实现方式吧。请教一下,这两种实现方式哪种更加好一点
    wizardforcel
        8
    wizardforcel  
       2016-02-24 13:13:02 +08:00 via Android
    泛型的类型参数只在编译时存在,编译之后会被擦除。比如你的 Singleton<String>和 Singleton<Integer>编译之后都是 Singleton , T 会变成 Object 。你是希望 Singleton<String>和 Singleton<Integer>有不同的 instance ,但实际上它们是冲突的,为了避免这种情况所以不能这么写。
    SoloCompany
        9
    SoloCompany  
       2016-02-24 13:58:41 +08:00
    @cmuler 模板衍生类互相之间没有一个公共的基类,类型不相容(更别谈赋值相容了),并且类的数量不好彩的话会爆炸(要知道泛型是嵌套的,考虑一下 List<List<List<Map<?,?>>>>)
    其实这点内存占用还不是最要命的,最要命的是没有公共基类了,就别想有任何兼容性可言了,也就是说,之前已经写好的(包括大量第三方)类库,都无法使用泛型版本的类,除非改写为只适用于某特定泛型版本的。 Java 里面也有这样的例子,你看一眼 java.uitil.Arrays 的实现就知道了,就是一个典型的模板方式实现的泛型,因为基本类型不是 Object 。
    其实 java 也可以创造一种模板方式的泛型语法,比如增加一个关键字 template , Arrays.binarySearch 就可以这样定义
    public static <template t> binarySearch(t[] a, t key);
    然后让编译器来动态生成每一种类型对应的方法
    可以说这两种泛型完全是不同的概念
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5785 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 41ms UTC 02:26 PVG 10:26 LAX 18:26 JFK 21:26
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86