帮助克隆方法

时间:2011-08-05 17:13:48

标签: java

我差不多完成了这个项目,涉及在Celsius,Fahrenheit和Kelvin之间转换,我最后需要的是找出克隆方法。任务是“clone,它不接受任何形式参数,并返回对新创建的Temperature对象的引用,该对象具有与其克隆对象相同的值和比例”。我的代码编译,但在客户端程序中运行时,我收到 java.lang.StackOverflowError的错误     在Temperature.clone(Temperature.java:134)

public class Temperature {
    private double value;
    private String scale;

    public Temperature() { // default constructor 
        this.value = 0;
        this.scale = "C";
    }

    public Temperature(double value, String scale) {
        this.value = value;
        this.scale = scale;
    }

    public double getValue() {
        return this.value;
    }

    public String getScale() {
        return this.scale;
    }

    public double getCelsius() {

        if (scale.equalsIgnoreCase("C")) {
            return this.value;
        } else if (scale.equalsIgnoreCase("F")) {
            double faren = ((this.value - 32) * (5 / 9));
            return faren;
        } else {
            double kelvin = (this.value - 273.15);
            return kelvin;
        }
    } // end getCelcius

    public double getFaren() {
        if (scale.equalsIgnoreCase("F")) {
            return this.value;
        } else if (scale.equalsIgnoreCase("C")) {
            double celsius = ((this.value * 1.8) + 32);
            return celsius;
        } else {
            double kelvin = ((this.value * 1.8) - 459.67);
            return kelvin;
        }
    } // ene getFaren

    public double getKelvin() {
        if (scale.equalsIgnoreCase("K")) {
            return this.value;
        } else if (scale.equalsIgnoreCase("C")) {
            double celsius = (this.value + 273.15);
            return celsius;
        } else {
            double faren = ((this.value + 459.67) * (5 / 9));
            return faren;
        }
    } // end getKelvin

    public void setTemperature(Temperature t) {
        this.value = t.value;
    }

    public void setType(double degree, String measure) {
        this.value = degree;
        this.scale = measure;
    }

    public void setValue(double degree) {
        this.value = degree;
    }

    public void setScale(String measure) {
        this.scale = measure;
    }

    public double convertToCelsius() {
        this.scale = "C";
        return this.value = getCelsius();
    }

    public double convertToFaren() {
        this.scale = "F";
        return this.value = getFaren();
    }

    public double convertToKelvin() {
        this.scale = "K";
        return this.value = getKelvin();
    }

    public Temperature clone() {
        this.value = value;
        this.scale = scale;
        return clone();
    }
}

克隆方法是最后一种方法,所以任何帮助都会受到赞赏。我不确定我哪里出错了!这是我第一次使用这个网站,所以对格式化道歉!

7 个答案:

答案 0 :(得分:6)

我不想给你一个家庭作业项目的答案,这是不赞成的。但是,你的clone()方法的问题很难......模糊不清。

public Temperature clone()

方法标题看起来很棒。您正在返回温度类型,它可以公开访问。

this.value = value;
this.scale = scale;

你知道'this'关键字的作用吗?它指的是调用该方法的对象。所以,如果我有一个温度对象'a'而我想调用a.clone(),这将设置一个等于... a的值的值。

return clone()

这是显示您的大问题的部分。你在实际上告诉java在这里做什么?无论clone()方法返回什么,你都告诉它返回。这意味着克隆将调用自身,这将再次调用自身... on到堆栈溢出。这是一个无法退出的递归循环。

请记住,您希望clone()返回 温度对象。

答案 1 :(得分:2)

您无意中使clone()成为递归方法而没有终止方法。

此外,Object.clone()只会返回副本。如果您尝试返回副本,我建议您使用copy constructor

答案 2 :(得分:1)

您获得堆栈溢出的原因是因为这一行:

return clone();

您是否了解过递归?这一行是从里面的克隆方法调用克隆方法...这种方法一直在反复发生......好吧,直到堆栈用完了空间!

您想要返回一个新对象,而不是返回clone()

答案 3 :(得分:1)

您不需要对基本字段和不可变类型的字段(如scale)执行任何操作。所以你在clone()中做得太多了。还需要调用super和Cloneable。

答案 4 :(得分:0)

public Temperature clone()
{
    return new Temperature(this.value, this.scale);
}

这就是你应该需要的。您编写的方法只是将调用对象的字段分配给自己,然后调用自身。最终它在没有真正做任何事情的情况下通过调用自身溢出堆栈。

答案 5 :(得分:0)

如果您想使用Object的{​​{3}}方法,必须实施clone界面。

根据文件

  

在未实现Cloneable接口的实例上调用Object的clone方法会导致抛出CloneNotSupportedException异常。

public class Temperature implements Clonable // just this will work for your requirement
{
    // other code

    public Temperature clone() {
        return super.clone() //this will server your purpose of cloning your temperature object.
    }

}

但遵循这种方式并不是一个好主意。最好从这个对象创建一个新实例。

StackOverflowError的原因是,你反复调用clone方法,它永远不会返回。

答案 6 :(得分:0)

在许多情况下,clone()不是可行的方法。显然,如果你的教练需要它,你必须写它并包括implements Clonable

否则编写复制构造函数通常更简单:

public Temperature(Temperature original) { ... }

从旧Temperature实例构建新的Temperature实例。这与clone()具有相同的效果,但可以避免一些相关的问题。

要获得额外的功劳,你还有enum吗?如果是这样,那么您可能希望在此处使用enum