多亏了@fireshadow52,我设法想出了这个脚本,即sin的args[0]。但是,它会输出一个StackOverFlow error。这是什么,以及如何(如果可能)发现它们?
class SIN {
public static void main(String[] args) {
double result = sin(args[0]);
}
public double sin(x) { Math.sin(x); return sin(x); }
}发布于 2011-08-21 09:52:39
节选自an answer to a similar question。
参数和局部变量在堆栈上分配(对于引用类型,对象位于堆上,而变量引用该对象)。堆栈通常位于地址空间的上端,当它用完时,它会朝向地址空间的底部(即接近零)。
您的流程还有一个堆,它位于流程的底部。当你分配内存时,这个堆可以向你的地址空间的上端增长。正如您所看到的,堆有可能与堆栈“碰撞”(有点像techtonic plate!)。
Stack Overflow错误意味着堆栈(您的方法)溢出(自身执行太多次,以至于崩溃)。堆栈溢出错误通常是由糟糕的递归调用引起的。
通常,如果您的方法名中没有关键字void,请确保return值与方法名不同。否则,堆栈将溢出,导致程序崩溃。只需替换这些行:
Math.sin(x);
return sin(x);...with这一行...
return Math.sin(x);...and,你应该可以开始了!
有时,要找出一个程序何时会崩溃可能有点棘手:
Q:这个程序会崩溃吗?如果有,原因何在?
public void MultiplyByNintyNine(byte num) {
MultiplyByNintyNine(num * 99);
}A:实际上,这可能会崩溃,原因有两个:
后一种情况更合理;即使该方法实际上不会return任何东西,该方法仍然会被调用。
在某些情况下,完全可以对方法名执行return。不过,如果你这样做了,请确保你有一个终止条件!下面是一个与你的类似的例子(不会崩溃):
import java.io.*;
//class declaration here
public static void main(String[] args) {
System.out.println(guessTheNumber());
}
public String guessTheNumber() {
int guess;
System.out.print("Guess the number:_");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
guess = Integer.parseInt(br.readLine());
} catch (NumberFormatException e) {
System.err.println("You didn't guess a number.");
guessTheNumber();
} catch (IOException e) {
System.err.println("An unexpected error occured. Please try again.");
guessTheNumber();
}
if (guess == 4) {
return "YAY! You get a prize!";
} else {
System.err.println("WAAHH! You get to guess again!");
guessTheNumber();
}
}警告:停止此代码(从代码本身)的唯一方法是输入4。
在上述情况下,当用户输入实际数字且该数字为4时,就会出现终止条件。
P.S.如果你情绪低落,here is a StackOverFlow error!
发布于 2011-08-21 09:52:56
我不确定为什么它会给出一个stackoverflow错误,但这不是有效的java。
sin方法没有声明输入参数的类型。字符串args需要转换为双精度,Math.sin才能工作。类名违反了java编码约定(不是错误)。错误应该已经被java编译器检测到。编译器抛出错误了吗?
发布于 2011-08-21 09:50:36
您的sin方法正在调用自身,因此这将无限期地继续下去,直到您达到调用堆栈限制时才会出现异常。为什么不直接返回Math.sin()呢?
https://stackoverflow.com/questions/7135853
复制相似问题