为何Java代码中直接调用rawBinary(d).length()-1会触发索引越界异常?
静态变量累积+参数执行顺序导致的索引越界异常
核心原因
你的代码存在两个关键问题:
- 静态变量未重置:
binS和reversedBin是类级静态变量,每次调用rawBinary或reverse时,都会在原有内容上追加,不会自动清空重置。 - 方法参数的执行顺序:Java中方法参数是从左到右依次计算的,连续调用
rawBinary(d)时,binS被多次修改,前后两次调用的返回值完全不同。
具体执行流程拆解
以你的main方法代码为例:
int d = 100; int x=rawBinary(d).length()-1; System.out.println(reverse( rawBinary(d) , rawBinary(d).length()-1 ));
1. 变量x赋值阶段
第一次调用rawBinary(100):
- 静态变量
binS初始为空,递归生成100的反转二进制字符串"0010011",长度为7,所以x=7-1=6。此时binS的值是"0010011"。
2. reverse方法调用阶段
此时要计算reverse的两个参数,从左到右执行:
- 第一步计算第一个参数
rawBinary(d):再次调用rawBinary(100),此时binS已有内容"0010011",方法会在其基础上继续追加100的反转二进制内容,最终binS变成更长的字符串(比如长度14),这个字符串作为reverse的第一个参数传入。 - 第二步计算第二个参数
rawBinary(d).length()-1:第三次调用rawBinary(100),binS在之前的基础上继续追加,变成更长的字符串(比如长度28),取长度减1得到27,作为reverse的第二个参数传入。 - 此时
reverse方法拿到的第一个参数是长度14的字符串,第二个参数是27,当方法执行到x.charAt(y)时,y=27远大于字符串最大索引13,直接触发StringIndexOutOfBoundsException。
为什么用变量x就正常?
当你改成reverse(rawBinary(d), x)时:
- 第一个参数
rawBinary(d)调用后,binS变成14长度的字符串,传入reverse。 - 第二个参数是之前计算好的
x=6,6小于14,索引有效,不会触发异常。
修复方案
去掉静态变量,每次调用方法时使用局部变量存储中间结果,避免内容累积:
public class decimalToBinary { static String rawBinary(int x) { String binS = ""; if (x == 0) { return binS; } return binS + x%2 + rawBinary(x / 2); } static String reverse(String x) { String reversedBin = ""; for (int y = x.length()-1; y >=0; y--) { reversedBin += x.charAt(y); } return reversedBin; } public static void main(String[] args) { int d = 100; String rawBin = rawBinary(d); System.out.println(reverse(rawBin)); } }
也可以用递归优化reverse方法:
static String reverse(String x) { if (x.isEmpty()) { return x; } return reverse(x.substring(1)) + x.charAt(0); }
内容的提问来源于stack exchange,提问作者Ayan
相关产品推荐
相关产品推荐

