【问题标题】:How to force toString() to print "undefined" instead of "null"如何强制 toString() 打印“未定义”而不是“空”
【发布时间】:2016-04-13 18:54:12
【问题描述】:

Fraction 对象为null 时,我正在尝试让toString 方法打印“未定义”。以下是我的类文件和测试器文件中的一些内容:

public class Fraction
{
    private int num;//Short for "numerator"
    private int den;//Short for "denominator"
    public Fraction(int a,int b)
    {
        num=a;
        den=b;
    }
    //Sample method that may result in a "null" object
    public Fraction divide(Fraction frac)
    {
        if(den!=0&&frac.den!=0)
            return new Fraction(num*frac.den,den*frac.num);
        return null;
    }

    public String toString()
    {
        simplify();
        if(this==null)
            return "undefined";
        if(den==0||this==null)
            return "undefined";
        if(den==1||num==den)
            return num+"";
        return num+"/"+den;
    }
}

public class FractionTest
{
    public static void main(String[]args)
    {
        Fraction f1=new Fraction(8,0);
        Fraction f2=new Fraction(2,1).divide(f1);
        System.out.println(f2);
        System.out.println(f2==null);
    }
}

不幸的是,代码产生了这个输出:

null
true

我能做些什么来解决这个问题?

【问题讨论】:

  • 你认为this==null 会做什么?你为什么这么认为?
  • 如果你能引用this,那就不是null
  • 这不能在Fraction 类中完成。你需要在课堂之外处理它。
  • 参考stackoverflow.com/help/mcve 您的示例将无法运行,部分原因是您没有向我们提供divide 函数 - 这可能有助于解释为什么您会得到这样的结果。

标签: java class tostring


【解决方案1】:

在 Java 中,this从不null。如果一段代码在null 对象上调用toString(),运行时将抛出NullPointerException

因此,您需要更改堆栈中较高的任何代码,以将可能-null Fraction 转换为字符串。这是实现目标的唯一途径。

【讨论】:

  • 很可能是String.valueOf,它检查空值并发出字符串文字“null”或调用对象的toString 方法。
  • 我不会说唯一的方法 - 如果方法协定继续返回 nullFraction 类表示未定义空间中的数字时,这是唯一的方法。但这可以在班级内部处理 - 他只是没有这样做。
【解决方案2】:

如果不提供divide 方法很难说,但是这段代码将f2 设置为null:

Fraction f2=new Fraction(2,1).divide(f1);
System.out.println(f2);

我们还可以看到System.out.println(null) 将打印null,所以您的输出是null 的原因是因为您将f2 设置为null

正如其他帖子所提到的,您不能在 null 引用上调用 toString:该引用具有没有可以调用的方法。因此,如果您想打印不同的内容,您需要创建一个函数,将null 值转换为所需的undefined 字符串。

但是!传递null 是不好的做法。您应该做的是将Function 定义为具有未定义的状态:

public class Fraction
{
    private enum STATE {
        DEFINED, UNDEFINED
    };

    //No reason to shorten private names
    private int numerator; 
    private int denominator;
    private STATE state;

    //Make your variable names meaningful!!!
    public Fraction(int numerator,int denominator)
    {
        this.numerator=numerator;
        this.denominator=denominator;
        this.state=STATE.DEFINED;
    }

    //Sample method that may result in a "null" object
    public Fraction divide(Fraction fraction)
    {
        if (fraction.denominator == 0){
            this.state = STATE.UNDEFINED;
            return this;
        }
        ...
    }

    public String toString()
    {
        simplify();
        if(this.state.equals(STATE.UNDEFINED)){
            return "undefined";
        } else {
            ...
        } //Note: you should always use braces for ifs
    }
}

在这个公式中,您利用 Java 的面向对象特性让 Fraction 对象本身知道它是否在您定义的数学空间上定义。我们知道没有为0 的分母定义分数,因此这是分数可能变得未定义的一种方式。然后,当您需要分数来报告其状态时,它可以。否则,程序中的每个其他类都需要知道如何处理未定义(即“null”)的分数,并且需要知道为 null 的分数与完全未定义的分数之间的区别充分的理由(例如除以零)。这很快就会变得难以管理。

【讨论】:

    【解决方案3】:

    你不能这样做,因为this不能是null,如果对象是null你不能调用toString方法,因为toString方法必须与对象相关。

    但您可以通过外部方法或使用包装类间接检查传递的对象是否为null,然后打印未定义

    【讨论】:

      【解决方案4】:

      实际上,使用this意味着对象存在,因此它不是null 解决方案是在 Fraction 类中定义 Fraction 类的静态实例,它代表一个null Fraction 对象。让我们说:

      public final static Fraction NULL_FRACTION = new Fraction (); // don't forget adding default constructor
      

      在你的devide方法中替换

      return null;
      

      return Fraction.NULL_FRACTION;
      

      toString方法中替换测试:

      this==null
      

      作者:

      Fraction.NULL_FRACTION.equals (this)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-10
        • 1970-01-01
        • 1970-01-01
        • 2018-12-20
        • 2021-11-27
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多