Java if null set default value

Working with Nulls in Java

In this article, we will learn some ways to deal with Null value in Java. Let’s get started.

Table of contents

Working with Reference types and Nulls

  1. Null and Reference types In the conference, in 2009, Sir Charles Antony Richard Hoare apologized for introducing null references in the programming language Algol Wz in 1965.
 I call it my billion-dollar mistake. It was the invention of the null reference in 1965. [. ] This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. 
  • Optional data Null is useful concept, it allows modeling optional data. For example, for certain the type of books, ISBN numbers are optional.
  • Unknown data Null also allow us to model data that hasn’t been entered yet, but it will be available at some point. For example, a book record can be created before the book’s finished and the exact number of pages is known.
  • Eager deinitialization Null can be used for either the initialization, too. For example, if a class manages its own memory, when an element is free, it should be noted out to avoid memory leaks.

From a technical point of view, null is a value that indicates that our reference does not refer to an object.

Читайте также:  Найти разницу между датами python

In assignment statement, it has three parts. The first part declares a reference variable. The second part creates an object of the type book telling the JVM to allocates space for a new book object in memory. Finally, the third part assigns the book object to a reference variable.

We also cannot meet the object creation, and in this case, the reference Book would refer to nothing at all because for all reference types, null is the default value. In other words, these two statements are equivalent.

 Book book; Book book = null; 

–> Nulls can be completely avoided in Java.

 public boolean isBookReadyForPublication(Book book)  assert book != null : "Book is null"; // . > 
 public boolean isBookReadyForPublication(Book book)  if (book != null)  // null != book // . > else  // . > > 
 public boolean isBookReadyForPublication(Book book)  Objects.requireNonNull(book, "Book is null"); // or if (Objects.isNull(book))  // Objects.nonNull(book) // book object is null > else  // do something with book object > > 
 public boolean isBookReadyForPublication(Book book)  try  // use book object > catch(NullPointerException ex)  // book object was null > > 

Use try/catch version will have better performance because there’s no checking for null. Exceptions may be a big cheaper in terms of performance. But using exception in this way, it’s about practice because it leads to go, hard to understand.

  • Best practices for data that we don’t control We can clarify the data that flows through an application in two types.
    • Given problem Below is an image that describes that our flow’s data in application. The data that we do not control is the data that is sent from Client to Server. It means that data from Presentation layer to Service layer.

    For parts of the application where we don’t have control of the data:

    • Document our public API It means that every class, interface, constructor, methods should have Java doc comments. For methods describe the contract:
      • preconditions
      • postconditions
      • parameters
      • return values

      • At the beginning of the method, use the general principle fail-fast.
      • If an invalid parameter value is passed to the method and the method checks for this before continuing its execution, it can take appropriate action. There are two options for this case:
        • Replace the null value with some default value such as using empty string, a negative value or an empty List. This solution is not always the right choice. It can cause the other errors.
        • Throw exceptions to indicate that an invalid value has been received. We can choose one of the NullPointerException or IllegalArgumentException and use it consistently. For example:
         public boolean isBookReadyForPublication(Book book)  Objects.requireNonNull(book, "Book is null"); Objects.requireNonNull(book.getAuthor(), "Author is null"); Objects.requireNonNull(book.getTitle(), "Title is null"); // business logic of this method // . > 
         public boolean publishBook(Book book, Date publicationDate)  // . > 

        In an above code, if the publicationDate variable is optional, instead of doing like the above code, it’s better to have the overloaded methods like the below.

         public boolean publishBook(Book book)  // . > 
         public HashSetEdition> getBookEditions()  return book.hasEditions() ? null : new HashSetEdition>(book.getEditions()); > 

        If null means that something could not be found, instead of using null value, we can return an empty collections.

         public HashSetEdition> getBookEditions()  return book.hasEditions() ? new HashSetEdition>() : new HashSetEdition>(book.getEditions()); > 

        Checking for Null using annotations

         ```java public class BookService < @NonNull private Integer defaultBookId; private void setDefaultBookId(@NonNull Integer id) < this.defaultBookId = id; >@NonNull private Integer getDefaultBookId() < return this.defaultBookId; >> 

        This annotation allows our object can be null. For example: «`java public interface BookRepository extends JpaRepository

      • @NonNullApi In order to configure this annotation, we have to define it in the package-info.java file of the root directory package.
      • @NonNullFields
    • Bean Validation Annotations Bean validation is the standard validation of specification, is defined by JSR 303 for its first version and JSR 380 for its second version. Some annotations that we need to know:
      • @NotNull
      • @Size
      • @Min/@Max
      • @PositiveOrZero

      Hibernate validator is the reference implementation of the specification, hibernate is associated with the persistent layer and that can be a source of confusion, especially about two things:

      • Does Hibernate Validator only validate objects of the domain model? No, it validates objects in all layers.
      • Are @NotNull and @Column(nullable = false) equivalent? No, the @Column annotation is part of the JPA specification. However, it doesn’t perform any validation if we annotate fields. If Hibernate creates the table, it adds a not null constraint to the database column, the database is the one that checks if the value is not null when we insert or update a record. @NotNull is a part of the Bean Validation specification. It triggers a validation during an update or persist lifecycle event. It validates at the applicaltion level. If it fail, Hibernate will not execute any SQL statement.
      • @NonNull annnotation for parameters of methods and constructors. It also used with the @Data annnotation

      To choose an annotation library, consider:

      • At what point the null check is performed.
      • Where we can use the annotations.
      • Tool and language interoperability and compability.

      Using the Null Object pattern

      In order to use Null Object pattern, we can refer the article Null Object pattern.

      So, instead of using a null reference to represent the absence of an object, it uses an object that implements the expected interface but does nothing, hiding the details from its collaborators.

      Some notes about Null Object pattern:

      • It’s not a kind of GoF patterns.
      • It was described in a article The Null Object pattern by Bobby Woolf. And later, it was published in the Pattern Languages of Program Design Vol.3.
      • The other names of this pattern are Active nothing, Stub.
      • The other pattern that has the same idea with this Null Object pattern is the Special pattern.

      Using Optional instead of Null

      Belows are some article we need to read:

      Wrapping up

      • Null is a value that indicates that a reference does not refer to an object.
      • The type of the literal value null is Null. That’s why use null with instanceof() will return false.
      • If we use null object, Java will throw a NullPointerException. To avoid a NullPointerException, developers traditionally use:
        • Assertions
        • If/else statements
        • Methods of the java.util.Objects class
        • And even try/catch blocks.

        It’s better to no overcomplicate things.

        Источник

        Checking for Nulls in Java? Minimize Using “If Else”

        In this article, I will try to give some examples of the different types of null checks or NPE (NullPointerException) avoidance techniques that is used.

        There are many good articles about this topic but I will try to focus on some specific examples from my own experiences.

        Note that, I am still in the learning process — probably never-ending :)- so, if you see any mistakes, feel free to let me know about it.

        1. java.util.Optional

        A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.¹

        One of the most common place Optional is used in the project that I am currently working on is while retrieving data from the database.

        Let’s say that you have 3 things:

        1. A model class called Student.java
        2. A service interface and its implementation: StudentService.java and StudentServiceImpl.java
        3. A DAO interface and its implementation: StudentDao.java and StudentDaoImpl.java

        and you want to retrieve the student with the related id.

        Optional.ofNullable()

        Returns an Optional describing the given value, if non-null, otherwise returns an empty Optional.¹

        Basically it is saying “first check if your student is null or not and then proceed”.

        // correct way to do it
        @Override
        public Student getStudentDirectly(Long id) final var studentOptional = studentDao.findStudentsById(id);
        if(studentOptional.isPresent()) // do your stuff here
        >
        >

        I mostly use get() in unit tests when I am sure that there is data returned from the method I called. But I would not use it without isPresent() in the actual code, even if I am sure that there will be no null.

        Another example; the below code piece tries to get the student with the related id and returns a default name (“Hayley”) if there is no such student. The value passed to rElse() is also returned when there is student but no name to it.

        @Override
        public String getStudentName(Long id) return studentDao.findStudentsById(id)
        .map(Student::getName)
        .orElse("Hayley");
        >

        2. Utility classes of apache.commons

        • For Collection instances: CollectionUtils.isEmpty() or CollectionUtils.isEmpty()
        • For Map instances : MapUtils.isEmpty() or MapUtils.isNotEmpty()
        • For String : StringUtils.isEmpty() or StringUtils.isNotEmpty()

        In case of lists, maps etc, isEmpty() checks if the collection/map is null or have size of 0. Similarly for String it checks if the String is null or have length of 0.

        As you see, you will get “400” error and in the console of your application you will see:

        DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void com.example.demodemo.controller.StudentController.saveStudent(com.example.demodemo.model.Student) with 2 errors: [Field error in object 'student' on field 'classes': rejected value [null]; 
        codes [NotEmpty.student.classes,NotEmpty.classes,NotEmpty.java.util.List,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.classes,classes]; arguments []; default message [classes]]; default message [must not be empty]] [Field error in object 'student' on field 'id': rejected value [null];
        codes [NotNull.student.id,NotNull.id,NotNull.java.lang.Long,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.id,id]; arguments []; default message [id]]; default message [must not be null]] ]

        If preferred, you can catch this MethodArgumentNotValidException and return a custom error.

        implementation 'org.springframework.boot:spring-boot-starter-validation'

        That was it for my current knowledge. I will try to update this list as I learn more ways to do null checks. There are times that I still need to use a good old “if else” block for null checking but I try to apply these methods whenever I can.

        Hopefully, you enjoyed this article.

        Источник

Оцените статью