首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  Java

为什么 Class 对象不能用==比较呢,但强转 Object 后就可以了?

  •  
  •   amiwrong123 · 55 天前 · 2121 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。

    System.out.println(Integer.class == String.class);这句就是不能通过编译的。

    但如果 System.out.println((Object) Integer.class == (Object)String.class);就可以通过编译了。(返回 false,顺便说一句)

    Integer.class 返回的不就是一个在堆上的 Class 对象吗,只不过它的类型是Class<Integer>,为啥它们两个不能用作操作符==比较呢?

    aguesuka
        1
    aguesuka   55 天前
    泛型不一样 左边是 Class<Integer> 右边是 Class<String>
    aguesuka
        2
    aguesuka   55 天前
    // ok
    boolean result = ((Class) String.class) == ( Integer.class);
    // 报错
    boolean result1 = ( String.class) == ( Integer.class);
    // 报错
    boolean result2 = new ArrayList<String>() == new ArrayList<Integer>();
    momocraft
        3
    momocraft   55 天前
    jawa 的泛型默認是不變 (invariant): Class<String>和 Class<Integer>沒有共通的祖先類, 是兩個 "完全無關" 的類型. 即使 String 和 Interger 有共同的祖先類 (Object).
    geelaw
        4
    geelaw   55 天前   ♥ 5
    @aguesuka #1 @momocraft #3 其实这并不是重点,Class<Integer> 和 Class<String> 都是 Object 的派生类(并不能说是“完全无关”),楼主想要问为什么引用比较不直接假设隐式转换为 Object 后引用比较。

    根据 JLS 12:

    15.21.3 Reference Equality Operators == and !=
    If the operands of an equality operator are both of either reference type or the null type, then the operation is object equality.
    It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal (ignoring the case where both values are null).
    ...

    如果 a == b 里面 a、b 的编译期类型分别是非 String 的引用类型 A、B,则必须存在 A 到 B 的隐式转换或存在 B 到 A
    的隐式转换,否则编译失败。这是一个人为限制,动机主要是绝大多数情况下这两个的比较结果都是“不引用相等”。

    只需要把一个比较运算数转换为 Object 即可编译成功。
    ZredoC
        5
    ZredoC   55 天前
    想了半天,发现想歪了

    楼主问的不是为啥 Integer.class 和 String.class 的 Class 对象的泛型不一样导致==结果返回 false

    而是为啥不能用 == 比较

    所以 #3 没有共同祖先类 的说法感觉靠谱

    。。

    == 是用于比较基本和引用数据类型的关系运算符

    Class 对象俩都不算的吧,所以编译报错了

    光记着比地址值,忽视了比的是啥
    ZredoC
        6
    ZredoC   55 天前
    打扰了,胡言乱语一通
    看#4
    SoloCompany
        7
    SoloCompany   55 天前 via iPhone
    只有赋值相容才可以用==比较,也就是说要么 a 能赋值给 b,或者相反,否则就是编译是错误,想明白这点是为什么就不难理解了
    amiwrong123
        8
    amiwrong123   55 天前
    @aguesuka
    boolean result = ((Class) String.class) == ( Integer.class); 所以右边的就可以隐式转换为泛型的原生类型了。
    amiwrong123
        9
    amiwrong123   55 天前
    @geelaw
    谢谢解答,直接解开了我的疑惑
    amiwrong123
        10
    amiwrong123   55 天前
    @ZredoC
    哈哈哈哈,不打扰不打扰
    amiwrong123
        11
    amiwrong123   55 天前
    @SoloCompany
    确实,赋值相容,就是代表可以隐式转换。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   727 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 20:34 · PVG 04:34 · LAX 12:34 · JFK 15:34
    ♥ Do have faith in what you're doing.