【问题标题】:java getSuperclass().toString() not running my custom toString()java getSuperclass().toString() 没有运行我的自定义 toString()
【发布时间】:2017-07-22 16:03:59
【问题描述】:

[大家好。我正在与 Cay Horstmann 的“真正不耐烦的 Java SE8”一起学习 Java。学习第四章]

我想调用父类的toString() 方法并为其添加一些东西。不幸的是,对父类的toString() 方法的调用似乎不起作用。

到目前为止,我已经学习了这些课程:

public class Point {
    private double _x = 0;
    private double _y = 0;

    public Point(double x, double y) {
        _x=x;
        _y=y;
    }

    @Override
    public String toString() {

        String theString = getClass().getSuperclass().toString() + " => " + getClass().getCanonicalName();

        theString += "[";
        int i=0;
        for (Field theField : getClass().getDeclaredFields()) {
            theField.setAccessible(true);
            try {
                if (i>0) theString += ", ";
                theString += theField.getName() + ": " + theField.get(this).toString();
                i++;
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Point.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("err1");
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Point.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("err2");
            }
        }
        theString += "]";
        return theString;
    }
    ...        
}

public class LabeledPoint extends Point {
    private String _label = "";

    public LabeledPoint(String label, double x, double y) {
        super(x, y);
        this._label = label;
    }

    ...

}

我用这个main 方法给他们打电话:

public static void main (String[] args) {
    LabeledPoint lp1 = new LabeledPoint("FirstPoint", 10.5, 30);
    System.out.println("The new point is:");
    System.out.println(lp1);
}

所以,我期待得到这样的东西:

Point[_x: 10.5, _y:30.0]=>LabeledPoint[_label: FirstPoint]

但相反,我得到

Point=>LabeledPoint[_label: FirstPoint]

也就是说,getClass().getSuperclass().toString()执行Point.toString(),但它只是打印出规范名称。

这是为什么呢?

【问题讨论】:

  • 您在class(不是实例)上调用toString()
  • 太棒了!那么,我该如何调用这个实例的父级toString() 方法呢?我试过super.toString()但我得到了Object.toString()方法,即:LabeledPoint@7852e922=>...
  • 您没有在代码中显示您已在 LabeledPoint 中覆盖 toString。因此,当您在 lp1 上调用 toString 时,实际上是在调用其父类 Point 的 toString。

标签: java reflection tostring superclass


【解决方案1】:

你似乎需要super.toString() 而不是getClass().getSuperClass().toString()

【讨论】:

  • 谢谢,Codebender,但我尝试了super.toString() 但我得到了Object.toString() 方法,即:LabeledPoint@7852e922=>...
  • @JoseVelas 那是因为它在PointtoString()方法中,所以超类是Object。你的意思是把那个代码放在LabeledPoint吗?
  • @bcsb1001:如果我将该代码放入 LabeledPoint,那么我会得到相同的结果:LabeledPoint@7852e922=>LabeledPoint[_label: FirstPoint]。我想做的是使用“反射”来不必关心调用toString() 方法的子类,它总是会打印出Point 中声明的字段。即:Point中声明的字段和LabeledPoint中声明的字段
【解决方案2】:

好的,伙计们。 (我不知道这有多好,但它确实有效)

Point 类如下所示:

public class Point {
    private double _x = 0;
    private double _y = 0;

    public Point(double x, double y) {
        _x=x;
        _y=y;
    }

    @Override
    public String toString() {

        String theString =  super.toString() + "=>" + getClass().getCanonicalName();

        //The following creates an array of fields that includes the parent 'Point's fields if the object is an instance of a direct child class of Point
        Field[] theFields;
        if (this.getClass() == Point.class) {
            theFields = getClass().getDeclaredFields();
        } else {

            theFields = new Field[Point.class.getDeclaredFields().length+getClass().getDeclaredFields().length];
            System.arraycopy(
                    Point.class.getDeclaredFields(), 
                    0, 
                    theFields, 
                    0, 
                    Point.class.getDeclaredFields().length
            );
            System.arraycopy(
                    getClass().getDeclaredFields(), 
                    0, 
                    theFields, 
                    Point.class.getDeclaredFields().length, 
                    getClass().getDeclaredFields().length
            );


        }

        theString += "[";
        int i=0;
        for (Field theField : theFields) {
            theField.setAccessible(true);
            try {
                if (i>0) theString += ", ";
                theString += theField.getName() + ": " + theField.get(this).toString();
                i++;
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Point.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("err1");
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Point.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("err2");
            }
        }

        theString += "]";

        return theString;
    }
    ...
}

【讨论】:

    猜你喜欢
    • 2017-04-15
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 2013-11-21
    • 2018-08-01
    • 2013-09-08
    • 1970-01-01
    • 2019-01-02
    相关资源
    最近更新 更多