java - 不可能的 nullPointerException 关于 java 反射
问题描述
最近我从第三方 jar 中遇到了 NullPointerException 问题,在我深入研究代码后仍然无法弄清楚它是如何发生的。这是错误堆栈跟踪
java.lang.NullPointerException
at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector._findPotentialFactories(AnnotatedCreatorCollector.java:183)
at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collect(AnnotatedCreatorCollector.java:57)
at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collectCreators(AnnotatedCreatorCollector.java:47)
at com.fasterxml.jackson.databind.introspect.AnnotatedClass._creators(AnnotatedClass.java:381)
at com.fasterxml.jackson.databind.introspect.AnnotatedClass.getFactoryMethods(AnnotatedClass.java:293)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.getFactoryMethods(BasicBeanDescription.java:534)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._addDeserializerFactoryMethods(BasicDeserializerFactory.java:852)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:349)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:269)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:1222)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:399)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
它说 npe 发生在 AnnotatedCreatorCollector 类的第 183 行,这是 AnnotatedCreatorCollector 的代码和行号
177 private List<AnnotatedMethod> _findPotentialFactories(JavaType type, Class<?> primaryMixIn)
178 {
179 List<Method> candidates = null;
180
181 // First find all potentially relevant static methods
182 for (Method m : ClassUtil.getClassMethods(type.getRawClass())) {
183 if (!Modifier.isStatic(m.getModifiers())) {
184 continue;
185 }
186 // all factory methods are fine:
187 //int argCount = m.getParameterTypes().length;
188 if (candidates == null) {
189 candidates = new ArrayList<>();
190 }
191 candidates.add(m);
192 }
我能想象这个 npe 会发生的唯一条件是局部变量“m”为空,然后我深入研究 ClassUtil 类,它就可以了
public static Method[] getClassMethods(Class<?> cls)
{
try {
return ClassUtil.getDeclaredMethods(cls);
} catch (final NoClassDefFoundError ex) {
// One of the methods had a class that was not found in the cls.getClassLoader.
// Maybe the developer was nice and has a different class loader for this context.
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null){
// Nope... this is going to end poorly
throw ex;
}
final Class<?> contextClass;
try {
contextClass = loader.loadClass(cls.getName());
} catch (ClassNotFoundException e) {
ex.addSuppressed(e);
throw ex;
}
return contextClass.getDeclaredMethods(); // Cross fingers
}
}
public static Method[] getDeclaredMethods(Class<?> cls) {
return cls.getDeclaredMethods();
}
我可以看到 ClassUtil 使用 java 反射返回一个方法数组,但我认为该数组不可能包含一个空对象,然后我就卡住了。
我的问题是:我们是否有可能通过java反射得到一个方法数组,并且该数组包含一个空对象?
这是我的代码
public class JsonUtil
{
...
public static <T> T strToObj(String str, Class<T> clazz)
{
try
{
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(str, clazz);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
...
}
解决方案
推荐阅读
- javascript - 反应:this.state 与 this.setState
- bokeh - 散景取消选中复选框
- reactjs - 如何在 webpack 中禁用“严格”模式?
- laravel - 带有队列的 Laravel 侦听器不执行
- c++ - 我可以用 premake 打印最终组装的 gcc 命令吗?
- python - Pandas read_fwf 难以解释类似日期的字符串
- node.js - npm install 漏洞对于不同的项目是不同的
- angular - Angular Schematics,修改 angular.json 的代码没有放在一起
- reactjs - 我们如何在 React Native 中使用 iOS 位代码支持?
- c++ - QAbstractTableModel headerData 删除标题