【问题标题】:Getter nullpointer without calling it获取空指针而不调用它
【发布时间】:2013-08-23 14:19:19
【问题描述】:

我在 getter 方法中遇到了 nullPointer 的问题。

代码如下:

 public String getTitle()
  {
    if(!title.isEmpty())
        return title;
    else 
        return "foo";
  }

当我将其更改为普通吸气剂时,它可以完美运行。

public String getTitle()
  {
    return title;
  }

诀窍在哪里?有反射技巧吗?

更新 问题不是空检查,而是执行getter而不调用它

堆栈跟踪

org.codehaus.jackson.map.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]- >si.mikropis.webkiosk.model.vao.wine.Wine["title"])

Caused by: java.lang.NullPointerException at si.mikropis.webkiosk.model.vao.base.BaseModel.getTitle(BaseModel.java:41) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:483) at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:418) at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) ... 32 more

【问题讨论】:

  • 我会发布您的完整堆栈跟踪。
  • 请添加您的 IDE(Netbeans、Android SDK,...)、包含的库(log4j、AndroidAnnotations,...)和使用的框架(例如 Hibernate、Struts,...)。
  • 我正在使用球衣和杰克逊。
  • @extra90:由于 JSON 解析器必须遍历对象的所有成员,因此可能没有出路。我能想到的唯一解决方案是要么告诉杰克逊不要包含null 值(检查stackoverflow.com/questions/11757487/…),要么尝试包含自定义映射器(例如参见wiki.fasterxml.com/JacksonHowToCustomSerializers);如果您关心性能,无论如何我都会选择 gson(请参阅stackoverflow.com/questions/338586/a-better-java-json-library
  • @extra90 - 您有以下多种解决方案来处理空值。但是,我会调查 为什么 你有空值。显然没有设置“标题”,这是一个不同的问题/问题/主题

标签: java nullpointerexception


【解决方案1】:

检查title 是否也为空:

  public String getTitle()
  {
    if(title != null && !title.isEmpty())
        return title;
    else 
        return "foo";
  }

p.s. 根据更新问题的附加评论:由于 JSON 解析器必须遍历对象的所有成员,因此可能没有简单的出路。我能想到的唯一解决方案是告诉杰克逊not to include null valuesimplement a custom mapper;如果性能是我最关心的问题,我会选择google-gson,因为他们的库非常好,而且比 Jackson 消耗的内存更少。

【讨论】:

  • 是的,但问题是 getter 正在执行而不调用它。
  • @extra90 在其中设置断点并在执行时检查堆栈跟踪。
  • 我认为这 解决了 OP 的问题。 getter 没有被显式调用
  • @extra90:“执行而不调用它”到底是什么意思?您是否使用任何可能调用 getter 的框架?
  • @JoachimIsaksson 创建对象时,会执行 getter。不知道为什么?
【解决方案2】:

我特别注意到您的评论 re。不调用 getter。许多框架使用JavaBean convention,因此如果您指定属性title,框架将调用getTitle()

例如在 Spring 中(并不意味着您正在使用 Spring):

<property name="title" value="abc"/>

会隐式调用你的 setter。

因此,您认为正在进行一些反思是正确的。我怀疑您在某处引用了 title 属性,并且使用的任何框架都在隐式调用您的 getter。如前所述,您的吸气剂中可能存在 NPE。断点会准确地告诉您它是如何被调用的。或者,事实上,您的异常堆栈跟踪。

编辑:我注意到您的堆栈跟踪,特别是:

org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:483)

这表明正在使用这种反射。

【讨论】:

  • setTitle 稍后出现,当创建对象时,我在开始时得到 NPE。我没有使用弹簧。
  • @Brian:尽管这解释了为什么调用 getter,但它并没有解释为什么第一个不应该工作。我不知道任何依赖于 getter 实现的框架......
  • @extra90 - 我并不是建议您使用 Spring。但我建议框架像这样工作,并且指定一个属性将导致相应的 setter/getter 被调用
【解决方案3】:

在这行

  if(!title.isEmpty())

titlenull

请添加nullcheck。但是签入getter不是一个好主意。而是

String title  ="foo"

public String getTitle()
  {
    return title;
  }

public String setTitle(String title)
    {
    this.title = title;
    }

【讨论】:

  • 我认为这并不能解决 OP 的问题。 getter 没有被显式调用
  • @BrianAgnew Ya,作为建议,我在第一行中解决了这个问题之后。
【解决方案4】:

如果您经常进行这些 null/empty 检查,则可能值得包含 Commons Lang

 return StringUtils.defaultIfBlank(title, "foo");

Null 安全并处理 Unicode 空白。

【讨论】:

    【解决方案5】:
     if(!title.isEmpty())
    

    您是直接对标题执行操作,而不检查它是否为空。你必须先做NPE检查

    if(title != null) {
    if(!title.isEmpty())
        return title;
     } 
     return "foo";
    

    【讨论】:

    • 我没有给出 getTitle() 的代码,我只是想强调 NPE 检查。无论如何编辑了我的代码。
    【解决方案6】:

    您的 title 对象为空,因此在其上调用 isEmpty 会引发空指针异常。

    title 即使在第二种选择中也是 null,但由于您没有在其上调用任何方法,因此它不会引发空指针异常。

    【讨论】:

      【解决方案7】:

      您也可以将标题定义为: 字符串标题 = "";

      【讨论】:

        【解决方案8】:

        我个人会在这里使用ternary 操作

        public String getTitle() {
           return (title !=null && !title.isEmpty()) ? title : "foo";
        }
        

        除此之外,我想说所有其他答案都能满足您的需求。

        【讨论】:

          【解决方案9】:

          标题可能是null

          public String getTitle() {
              if(title !=null && !title.isEmpty())
                  return title;
              else 
                  return "foo";
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-06-17
            • 1970-01-01
            • 1970-01-01
            • 2013-12-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多