【问题标题】:Call toString() when convert String to Object [duplicate]将字符串转换为对象时调用 toString() [重复]
【发布时间】:2017-10-07 14:00:02
【问题描述】:

这是我的示例代码:

String str = "hello";
Object obj = (Object)str;
System.out.println(obj.toString());

找到了Object的源码,toString()方法是:

public String toString() {   
   return getClass().getName() + "@" + Integer.toHexString(hashCode());
} 

我认为示例的结果应该是这个对象的地址,比如 [B@15db9742 ,在我将 str 转换为 Object 之后,但它仍然打印你好。为什么? obj不应该使用Object的方法吗?谁能给我解释一下它的原理?

【问题讨论】:

  • 欢迎来到polymorphism。 :-) (必须有一个欺骗目标。)
  • Method Overriding - 您只更改引用类型,实际对象仍然是 String 并且 StringtoString 返回实际字符串
  • ...但我没有找到一个非常好的。但这只是我没有时间搜索。
  • 你没有将String转换Object - 你是casting(在这种情况下,演员不是即使有必要,您也可以只做Object obj = str; 而不进行强制转换)。投射不会改变(即转换)对象。

标签: java


【解决方案1】:

这是polymorphism(具体来说,运行时多态)。您对对象的引用类型是什么(ObjectString)并不重要,只要该类型具有 toString(因此您的代码可以编译),将使用的 toString 是对象本身实际拥有的那个,不一定是您的引用类型提供的那个。在这种情况下,无论您对它的引用是什么类型,对象都是String,因此使用String#toString

【讨论】:

    【解决方案2】:

    因为底层对象是一个String对象,而String类已经覆盖了其中的toString()方法。

    尽管您在左侧有 Object 类型,但已实现 Class 中的方法会被执行,并且整体现象称为多态性。您只是将字符串的形式更改为对象。

    当你这样做时

    Object obj = (Object)str;
    

    这不会将 String 更改为 Object 类。您只是在更改 Object 的类型,而不是它的实际行为。

    【讨论】:

      【解决方案3】:

      Object obj 是(不必要的)强制转换的结果,但仍然是 String.... String 类实现了 toString 方法的覆盖:

      public String toString() {
          return this;
      }
      

      通过以下方式验证 obj 是否为字符串:

      System.out.println(str.getClass());
      System.out.println(obj.getClass());
      

      你会得到

      类 java.lang.String

      类 java.lang.String

      【讨论】:

        【解决方案4】:

        虚拟方法调用意味着将在给定实际实现的情况下执行方法覆盖,而不是引用类型中的实现。

        换句话说,即使转换为Object,您的String 实例仍将调用ObjectString 中实现的方法的覆盖。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-01-25
          • 2020-11-15
          • 1970-01-01
          • 1970-01-01
          • 2016-09-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多