How to avoid null checking in Java?

后端 未结 30 3277
失恋的感觉
失恋的感觉 2020-11-21 04:43

I use object != null a lot to avoid NullPointerException.

Is there a good alternative to this?

For example I often use:



        
相关标签:
30条回答
  • 2020-11-21 05:30

    Just don't ever use null. Don't allow it.

    In my classes, most fields and local variables have non-null default values, and I add contract statements (always-on asserts) everywhere in the code to make sure this is being enforced (since it's more succinct, and more expressive than letting it come up as an NPE and then having to resolve the line number, etc.).

    Once I adopted this practice, I noticed that the problems seemed to fix themselves. You'd catch things much earlier in the development process just by accident and realize you had a weak spot.. and more importantly.. it helps encapsulate different modules' concerns, different modules can 'trust' each other, and no more littering the code with if = null else constructs!

    This is defensive programming and results in much cleaner code in the long run. Always sanitize the data, e.g. here by enforcing rigid standards, and the problems go away.

    class C {
        private final MyType mustBeSet;
        public C(MyType mything) {
           mustBeSet=Contract.notNull(mything);
        }
       private String name = "<unknown>";
       public void setName(String s) {
          name = Contract.notNull(s);
       }
    }
    
    
    class Contract {
        public static <T> T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; }
    }
    

    The contracts are like mini-unit tests which are always running, even in production, and when things fail, you know why, rather than a random NPE you have to somehow figure out.

    0 讨论(0)
  • 2020-11-21 05:32

    Guava, a very useful core library by Google, has a nice and useful API to avoid nulls. I find UsingAndAvoidingNullExplained very helpful.

    As explained in the wiki:

    Optional<T> is a way of replacing a nullable T reference with a non-null value. An Optional may either contain a non-null T reference (in which case we say the reference is "present"), or it may contain nothing (in which case we say the reference is "absent"). It is never said to "contain null."

    Usage:

    Optional<Integer> possible = Optional.of(5);
    possible.isPresent(); // returns true
    possible.get(); // returns 5
    
    0 讨论(0)
  • 2020-11-21 05:33

    This is the most common error occurred for most of the developers.

    We have number of ways to handle this.

    Approach 1:

    org.apache.commons.lang.Validate //using apache framework
    

    notNull(Object object, String message)

    Approach 2:

    if(someObject!=null){ // simply checking against null
    }
    

    Approach 3:

    @isNull @Nullable  // using annotation based validation
    

    Approach 4:

    // by writing static method and calling it across whereever we needed to check the validation
    
    static <T> T isNull(someObject e){  
       if(e == null){
          throw new NullPointerException();
       }
       return e;
    }
    
    0 讨论(0)
  • 2020-11-21 05:35

    If you use (or planning to use) a Java IDE like JetBrains IntelliJ IDEA, Eclipse or Netbeans or a tool like findbugs then you can use annotations to solve this problem.

    Basically, you've got @Nullable and @NotNull.

    You can use in method and parameters, like this:

    @NotNull public static String helloWorld() {
        return "Hello World";
    }
    

    or

    @Nullable public static String helloWorld() {
        return "Hello World";
    }
    

    The second example won't compile (in IntelliJ IDEA).

    When you use the first helloWorld() function in another piece of code:

    public static void main(String[] args)
    {
        String result = helloWorld();
        if(result != null) {
            System.out.println(result);
        }
    }
    

    Now the IntelliJ IDEA compiler will tell you that the check is useless, since the helloWorld() function won't return null, ever.

    Using parameter

    void someMethod(@NotNull someParameter) { }
    

    if you write something like:

    someMethod(null);
    

    This won't compile.

    Last example using @Nullable

    @Nullable iWantToDestroyEverything() { return null; }
    

    Doing this

    iWantToDestroyEverything().something();
    

    And you can be sure that this won't happen. :)

    It's a nice way to let the compiler check something more than it usually does and to enforce your contracts to be stronger. Unfortunately, it's not supported by all the compilers.

    In IntelliJ IDEA 10.5 and on, they added support for any other @Nullable @NotNull implementations.

    See blog post More flexible and configurable @Nullable/@NotNull annotations.

    0 讨论(0)
  • 2020-11-21 05:36

    Probably the best alternative for Java 8 or newer is to use the Optional class.

    Optional stringToUse = Optional.of("optional is there");
    stringToUse.ifPresent(System.out::println);
    

    This is especially handy for long chains of possible null values. Example:

    Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
        .map(f -> f.getBar())
        .map(b -> b.getBaz())
        .map(b -> b.getInt());
    

    Example on how to throw exception on null:

    Optional optionalCarNull = Optional.ofNullable(someNull);
    optionalCarNull.orElseThrow(IllegalStateException::new);
    

    Java 7 introduced the Objects.requireNonNull method which can be handy when something should be checked for non-nullness. Example:

    String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();
    
    0 讨论(0)
  • 2020-11-21 05:37

    I like articles from Nat Pryce. Here are the links:

    • Avoiding Nulls with Polymorphic Dispatch
    • Avoiding Nulls with "Tell, Don't Ask" Style

    In the articles there is also a link to a Git repository for a Java Maybe Type which I find interesting, but I don't think it alone could decrease the checking code bloat. After doing some research on the Internet, I think != null code bloat could be decreased mainly by careful design.

    0 讨论(0)
提交回复
热议问题