【发布时间】:2012-09-03 15:04:17
【问题描述】:
堆栈跟踪很长,但这是相关部分。
Caused by: java.lang.ArrayIndexOutOfBoundsException: 33
at java.lang.String.equals(String.java:1018)
at java.util.HashMap.get(HashMap.java:305)
所以,当我从 HashMap<String,?> 检索一个元素时,会调用 String#equaqls。然后,从行 if (v1[i++] != v2[j++]) 抛出一个 ArrayIndexOutOfBoundException@
// Sun java 1.6
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
真的很奇怪。
更新。异常来自日志分析程序。我没有在那里使用反射。我还考虑过某些东西损坏了字符串对象,但没有从代码中得到任何线索。而且这个问题在重启后没有重现。不知道继续重试能不能重现。
-
LogUtils
public static Map<String, String> parseLine(String line) { if (StringUtils.isEmpty(line)) { return Collections.emptyMap(); } String[] parts = StringUtils.split(line, '\t'); Map<String, String> results = new HashMap<String, String>(); for (String part : parts) { String[] keyVal = StringUtils.split(part, "=", 2); if (keyVal.length == 2) { String key = keyVal[0]; String value = keyVal[1]; results.put(key, value); } } return results; } public static void process(String fileName, Date date, Closure closure) throws IOException { InputStream is = null; Reader r = null; try { is = new FileInputStream(getFilename(fileName, date)); is = new BufferedInputStream(is); is = new GZIPInputStream(is); r = new InputStreamReader(is, "utf8"); LineIterator iter = IOUtils.lineIterator(r); while (iter.hasNext()) { String line = iter.nextLine(); Map<String, String> map = LogUtils.parseLine(line); closure.execute(map); } } finally { IOUtils.closeQuietly(r); IOUtils.closeQuietly(is); } } -
关闭
public void execute(Map<String, String> line) { if (dataMap == null) { dataMap = new HashMap<String, Map<Long, Integer>>(); } String identifier = line.get(Constants.IDENTIFIER_KEY); // Exception thrown from there /* ...blahblah... */ }
为了简单起见,我将创建一个闭包对象并用它调用LogUtils.process。 LogUtils 换行(例如:key1=value1\tkey2=value2\t...kn=valuen)喜欢它变成HashMap。然后LogUtils 会将地图传递给闭包。当 Constants.IDENTIFIER_KEY 是静态最终字段时,从 line.get(Constants.IDENTIFIER_KEY); 抛出异常。所以equals方法的lhs和rhs是一个静态的final String,返回值为StringUtils.split(line, '\t')。我检查了 commons-lang 的代码。实际上是String#substring。所以还是很奇怪。
【问题讨论】:
-
这表明 i 或 j 超出了该数组的限制。
-
@veer:我不这么认为。想象一下,如果
n以 0 开头...对于您的版本,它将永远不会终止。 -
@yegong 你能告诉我们更多代码吗?例如插入和访问
Map的内容。 -
@JonSkeet equals 方法的代码不是我的实现。它是 java 1.6 的源代码。
-
@Rhyono 确定。但它是 java.lang.String#equals。此处不应出现 ArrayIndexOutOfBoundException。
标签: java