我差不多完成了这个项目,涉及在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();
}
}
克隆方法是最后一种方法,所以任何帮助都会受到赞赏。我不确定我哪里出错了!这是我第一次使用这个网站,所以对格式化道歉!
答案 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
。