【问题标题】:Why is the toString() method being called when I print an object?为什么打印对象时会调用 toString() 方法?
【发布时间】:2011-12-18 23:44:21
【问题描述】:

我似乎无法理解为什么当我对季度对象使用 println 方法时,它会返回 toString 方法的值。我从来没有调用过 toString 方法为什么我得到了返回值?

public class Main {
    public static void main(String[] args) {
        Quarter q = new Quarter();
        Nickel n = new Nickel();
        System.out.println(q);
        System.out.println(n);
    }
}

public abstract class Money {
    private int value;

    public Money(int v) {
        value=v;
    }

    public abstract int getValue();

    protected int myValue() {
        return value;
    }

    public abstract String toString();
}

public abstract class Coin extends Money {
    public Coin(int value) {
        super(value);
        System.out.println("I am a coin, my value is " + getValue());
    }
}

public class Quarter extends Coin {
    public Quarter () {
        super(25);
    }

    public int getValue() {
        return myValue();
    }

    public String toString() {
        return "A Quarter is "+getValue();
    }
}

public class Nickel extends Coin {
    public Nickel () {
        super(5);
    }

    public int getValue() {
        return myValue();
    }

    public String toString() {
        return "A "+this.getClass().getName()+ " is "+getValue();
    }
}

【问题讨论】:

  • 您认为您的季度对象的字符串表示形式是什么?你不能只告诉 java 打印你的对象。

标签: java object


【解决方案1】:

关于参考 java 文档我不明白的是,

当您调用 PrintStream 类 print(obj) / println(obj) 方法时,它在内部调用 write 方法,参数为 String.valueOf(obj) 如下图:

public void print(Object obj) {
    write(String.valueOf(obj));
}

现在 String.valueOf(obj) 完成调用 String 方法的任务,如下所示:

 /**
 * Returns the string representation of the <code>Object</code> argument.
 *
 * @param   obj   an <code>Object</code>.
 * @return  if the argument is <code>null</code>, then a string equal to
 *          <code>"null"</code>; otherwise, the value of
 *          <code>obj.toString()</code> is returned.
 * @see     java.lang.Object#toString()
 */
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

【讨论】:

    【解决方案2】:

    因为PrintStream.println 有一个重载,它接受Object,然后调用它的toString 方法。

    【讨论】:

      【解决方案3】:

      因为这个函数是这样操作的:它为你格式化原始类型,但是当你传递一个对象时,它会调用.toString()

      如果你不覆盖它,它将输出默认的.toString() 实现(Class@somenumber),这并不是真正有用的......

      【讨论】:

      • 哦,我明白了!我从来不知道。因此,如果我在 println 方法的参数中传递一个对象,我将默认调用该对象的 tostring 方法。它似乎没有用,它与我所了解的“除非你调用它,否则你不会使用方法”相矛盾。但感谢有关 println 方法的信息。 println 方法像这样调用 tostring 方法似乎相当偷偷摸摸。
      • @NicholasKong:“除非你调用它,否则你不会使用方法”;这仅适用于非覆盖方法。 toString 是基类方法的覆盖,因此可以被引用基类的事物调用。
      • 好吧,也许您更喜欢 C 版本,它尝试将所有内容打印为 0 终止 char *? :p
      • 好的,谢谢大家!无论如何,诸如 toString 之类的重写方法都会被调用!我会记住的。
      • 不,不要贸然下这样的结论。就像@OliCharlesworth 说的,真正的原因是因为System.out 是一个PrintStream,当这个类的print() 方法被一个Object 作为参数调用时,它实际上会打印这个对象的.toString() 的结果方法。现在,您的对象可能也可能不会覆盖.toString()
      【解决方案4】:

      当您直接尝试打印一个对象时,默认情况下它将调用toString 方法,您需要覆盖该toString 方法来打印您的类的属性。

      【讨论】:

        【解决方案5】:

        因为java中的所有类都是java.lang.Object的子类,所以每当你尝试调用System.out.println()方法来打印对象时,它都会调用Object类的toString()方法。

        出于安全原因,该方法打印哈希码,而不是该对象的值, 但是您在类中继承了该方法并将其定义扩展为打印对象值

        public String toString() {
                return "A Quarter is "+getValue();
            }
        

        所以你得到一个返回值。

        【讨论】:

          猜你喜欢
          • 2020-08-02
          • 2014-05-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多