【问题标题】:String Literal and Object Literal comparison字符串文字和对象文字比较
【发布时间】:2020-04-22 20:50:57
【问题描述】:

我想出了这个场景,但无法理解其背后的逻辑? 我只看懂了第一个,剩下的两个看不懂?请解释它在内部是如何工作的?

public class Test {
    public static void main(String[] args) {

        String s = "Karan";
        Object o = "Karan";

        System.out.println(s.equals(o));         // True
        System.out.println(o.equals(s));        // True 
        System.out.println(s == o);            // True
    }
}

【问题讨论】:

  • 因为两者都是字符串字面量并且指向字符串常量池中的相同引用
  • 没有“对象文字”,两者都是字符串文字(由于字符串常量池被解析为同一个实例),一个恰好被分配给类型为Object的变量而不是String。然而,对象本身仍然是String
  • 你能再精确一点吗?究竟是什么令人困惑,为什么?
  • "但我们正在创建对象类型的字符串" 不,在Object o = "Karan"; 的情况下,我们正在创建(或实际上从字符串常量池重用)字符串类型的 object 和我们将 reference 存储在 Object 类型的 variable 中。
  • @MandarDharurkar 不,这不是重复的。

标签: java string object equals string-literals


【解决方案1】:

对象的静态类型和变量的动态类型是有区别的。

静态类型是编译时已知的类型。对于Object o = "Karan";,静态类型是o左边的那个,即Object。现在,有人可能会问为什么会这样,因为在编译时,可以推断出oString。好吧,如果我们考虑类似的事情

Object o;
if (someCondition) {
    o = "Karam";
} else {
    o = new StringBuffer();
}

那么我们无法知道oString还是StringBuffer,因此它的静态类型是Object(因为o被定义为Object)。

动态类型是运行时的类型。在上面的示例中,在执行if 语句之后,o 要么是String 要么是StringBuffer,但不是两者兼而有之。在您的示例中,Object o = "Karan"; 的动态类型为 String

当变量通过equals(...) 进行比较时,它们必须具有相同的动态类型才能使比较返回true(请注意,此属性是必需的,但还不够)。由于您的示例中的o 实际上是String 并且内容等于s, s.equals(o) == o.equals(s) == true

至于s == o为什么返回true:问题在this post回答。

【讨论】:

  • 从技术上讲,“静态类型”只对变量很重要。 对象只有动态类型。了解对象和引用该对象的变量之间的区别对于这个问题非常重要。
  • 确实如此。我改写了我的答案。
【解决方案2】:

String s = "Karan" 这是一个由字符串引用引用的字符串对象。

Object o = "Karan" 这是一个由 Object 引用引用的 String 对象。超类可以引用子类的对象。

对于s.equals(o)o.equals(s) 都调用底层对象equal(),因为对象是String 类型(即使引用'o' 是Object 类型)调用String 的equals 比较相等的字符串。这就是你得到true 的结果。

s == o比较s和o的对象引用。它们是使用 双引号 创建的,它使用字符串池,创建一次对象并再次引用它。所以 s 和 o 都是完全相同的 String 对象。这使得== 返回真。

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 1970-01-01
    • 2015-02-11
    • 2020-02-02
    • 1970-01-01
    • 2013-03-24
    • 2018-10-17
    • 1970-01-01
    相关资源
    最近更新 更多