我在使用jdk1.8的程序中遇到了一个相当奇怪的情况, 我在 String.length (位于 StringBuilder.append() 中)方法中遇到了空指针异常,
空指针异常的具体位置在jdk的String中,
public int length() {
return value.length; //line 623
}
它在 AbstractStringBuilder 类中被调用:
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length(); //here line 447
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
我无法理解这是如何发生的,因为在调用 str.length() 之前有一个空检查。
也许由于同样的原因,我尝试打印字符串内容一路崩溃,所以我无法获取是什么字符串内容导致了这个。
现在,我想知道是什么导致了这个问题,我可以构建一个字符串内容来重现这个问题吗?感谢您的任何想法。
堆栈跟踪
java.lang.NullPointerException
at java.lang.String.length(String.java:623)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:447)
at java.lang.StringBuilder.append(StringBuilder.java:141)
at ....toString(....java:14) //a toString method of some class
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at java.util.AbstractCollection.toString(AbstractCollection.java:462)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at com
我在这两种环境中都得到了这个:
java 版本“1.8.0_102”Java(TM) SE 运行时环境(构建 1.8.0_102-b14) Java HotSpot(TM) 64 位服务器 VM(版本 25.102-b14,混合模式)
和
openjdk版本“1.8.0_345”OpenJDK运行时环境 (Temurin)(build 1.8.0_345-b01) OpenJDK 64 位服务器虚拟机 (Temurin)(build 25.345-b01,混合模式)
我能够以一种相当复杂的方式重现这个错误,我怀疑这可能是错误发生的。
String
类有一个受包保护的构造函数,它接受 char[]
和 boolean
(实际上并未使用)。这个构造函数仅供内部使用,只是简单地存储 char[]
而不对其执行任何验证。
你可以使用反射来调用它,并产生所描述的
NullPointerExcpetion
:
// Use reflection to invoke "new String((char[]) null, true)";
Constructor<String> ctor =
String.class.getDeclaredConstructor(char[].class, boolean.class);
ctor.setAccessible(true);
String s = ctor.newInstance(null, true);
StringBuilder sb = new StringBuilder();
sb.append(s); // Null pointer exception when calling String.length