If by legal you mean by using the constructors and methods exposed by the String
API, then, no, it is not possible to reproduce such an exception.
There are ways to instantiate classes that will skip constructors and initializers. sun.misc.Unsafe
provides such a utility, allocateInstance
.
public static void main(String[] args) throws Exception {
String string = (String) getUnsafe().allocateInstance(String.class);
System.out.println(string.length());
}
@SuppressWarnings("restriction")
private static Unsafe getUnsafe() {
try {
Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
singleoneInstanceField.setAccessible(true);
return (Unsafe) singleoneInstanceField.get(null);
} catch (Exception e) {
}
return null;
}
In this case, the value
field of String
will remain null
and the NullPointerException
will occur when invoking length()
.
Similarly, some proxying libraries that use byte code manipulation can omit an invocation to super()
when creating proxy subclasses, effectively skipping initialization. Here's a related question where mocking failed to properly initialize an ArrayList
's backing array.