search

Home  >  Q&A  >  body text

What is NullPointerException and how to fix it?

<p>What are Null Pointer Exceptions (<code>java.lang.NullPointerException</code>) and what cause them? </p> <p>What methods/tools can be used to determine the cause so that the exception can be prevented from causing the program to terminate prematurely? </p>
P粉649990273P粉649990273462 days ago616

reply all(2)I'll reply

  • P粉252116587

    P粉2521165872023-08-24 09:14:35

    NullPointerException is an exception that occurs when you try to use a reference to any location in memory (null), just like a reference to an object. Calling a method on a null reference or trying to access a field with a null reference will trigger a NullPointerException. These are the most common, but other methods are listed in the NullPointerException javadoc page.

    The fastest example code I can think of to illustrate NullPointerException is probably:

    public class Example {
    
        public static void main(String[] args) {
            Object obj = null;
            obj.hashCode();
        }
    
    }

    In the first line within

    main, I explicitly set the Object reference obj to null. This means I have a reference, but it doesn't point to any object. Afterwards, I try to treat the reference as pointing to an object by calling its methods. This results in a NullPointerException because there is no code to execute at the location pointed to by the reference.

    (This is a technical question, but I think it's worth mentioning: a reference to null is not the same as a C pointer pointing to an invalid memory location. A null pointer doesn't actually point to anywhere, unlike pointing to exactly one Invalid positions are slightly different.)

    reply
    0
  • P粉593536104

    P粉5935361042023-08-24 00:10:48

    There are two main types of variables in Java:

    1. Primitive: Variable containing data. If you want to manipulate the data in the original variable, you can manipulate the variable directly. By convention, primitive types begin with a lowercase letter. For example, variables of type int or char are primitives.

    2. Reference : A variable containing the memory address of the object , that is, a variable that references the object Code>. If you want To operate on the Object referenced by a reference variable, you must dereference it. Dereferencing typically requires using . to access a method or field, or [ to index an array. By convention, reference types are usually represented by the type starting with an uppercase letter. For example, variables of type Object are references.

    Consider the following code, in which you declare a primitive variable of type int but do not initialize it:

    int x;
    int y = x + x;
    

    These two lines will crash the program because no value has been specified for x and we are trying to use the value of x to specify y >. All primitives must be initialized to usable values ​​before they can be manipulated.

    Now things get interesting. References variables can be set to null, which means "I'm not referencing anything". If you explicitly set a reference variable in this way, you can get a null value in the reference variable, or the reference variable is not initialized and the compiler doesn't catch it (Java automatically sets the variable to null ).

    If you set a reference variable to null, either explicitly or automatically via Java, and you try to dereference it, you will get a NullPointerException.

    A NullPointerException (NPE) typically occurs when you declare a variable but do not create an object and assign it to the variable before trying to use the variable's contents. So you're referencing something that doesn't actually exist.

    Use the following code:

    Integer num;
    num = new Integer(10);

    The first line declares a variable named

    num, but it doesn't actually contain a reference value yet. Since you haven't said what you want to point to, Java sets it to null.

    In the second line, the

    new keyword is used to instantiate (or create) an object of type Integer, and the reference variable num is assigned to the Integer Object.

    If you try to dereference

    num before creating the object, , you will get a NullPointerException. In the simplest case, the compiler will catch the problem and let you know "num may not have been initialized", but sometimes you may write code that doesn't create the object directly.

    For example, you might have a method like this:

    public void doSomething(SomeObject obj) {
       // Do something to obj, assumes obj is not null
       obj.myMethod();
    }

    In this case you do not create the object

    obj but assume it was created before calling the doSomething() method. Note that the method can be called like this:

    doSomething(null);

    In this case,

    obj is null and the statement obj.myMethod() will throw NullPointerException >.

    If the method is intended to perform some operation on the object passed in like the method above, it is appropriate to throw

    NullPointerException because this is a programmer error and the programmer needs that information for debugging Purpose.

    In addition to NullPointerException exceptions thrown due to method logic, you can also check for null values ​​in method parameters and explicitly throw an NPE by adding something like: Followed near the beginning of the method:

    // Throws an NPE with a custom error message if obj is null
    Objects.requireNonNull(obj, "obj must not be null");

    Note that it would be helpful to explicitly state which object cannot be null in the error message. The advantages of validating this are that 1) you can return your own clearer error message, 2) for the rest of the method you know that obj is not null unless it is reallocated and can be safely dereferenced.

    Alternatively, in some cases, the purpose of the method is not just to operate on the object passed in, so an empty parameter may be acceptable. In this case you need to check for null arguments and behave differently. You should also explain this in the documentation. For example, doSomething() can be written as:

    /**
      * @param obj An optional foo for ____. May be null, in which case
      *  the result will be ____.
      */
    public void doSomething(SomeObject obj) {
        if(obj == null) {
           // Do something
        } else {
           // Do something else
        }
    }

    Finally, How to use stack traces to pinpoint exceptions and causes

    Sonar with the Find Error feature can detect NPE. Can sonar dynamically capture null pointer exceptions caused by JVM

    Now Java 14 adds a new language feature to show the root cause of NullPointerException. This language feature has been part of the SAP Business JVM since 2006.

    In Java 14, the following is an example NullPointerException exception message:

    List of situations that lead to NullPointerException

    The following are all situations in which a NullPointerException is directly mentioned by the Java Language Specification:

    • Access (i.e. get or set) the instance field of a null reference. (Static fields don’t count!)
    • Call the instance method of a null reference. (Static methods do not count!)
    • Throws null value;
    • Access elements of an empty array.
    • Synchronize on null - synchronized (someNullReference) { ... }
    • Any integer/floating point operator may throw NullPointerException
    • if one of its operands is a boxed null reference.
    • If the boxed value is null, the unboxing conversion throws a NullPointerException.
    • Calling super on a null reference will throw NullPointerException. If you're confused, this is talking about qualified superclass constructor calls:
    class Outer {
        class Inner {}
    }
    class ChildOfInner extends Outer.Inner {
        ChildOfInner(Outer o) { 
            o.super(); // if o is null, NPE gets thrown
        }
    }
    • Use for (element : iterable) loop to loop through an empty collection/array.

    • switch (foo) { ... } (whether an expression or a statement) can throw NullPointerException when foo is empty .

    • foo.new SomeInnerClass() Throws NullPointerException when foo is null.

    • Method references of the form
    • name1::name2 or primaryExpression::name will throw NullPointerException name1# when evaluated in the following cases ## or primaryExpression evaluates to null.

      The comment from JLS states that

      someInstance.someStaticMethod() does not throw an NPE because someStaticMethod is static, but someInstance::someStaticMethod still Throw NPE!

    * Please note that JLS may also indirectly talk a lot about NPE.

    reply
    0
  • Cancelreply