View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3.function;
19  
20  import java.util.function.Supplier;
21  
22  import javax.annotation.Nonnull;
23  import javax.annotation.Nullable;
24  
25  import org.apache.commons.lang3.ObjectUtils;
26  
27  /**
28   * This class provides some replacements for the corresponding methods in
29   * {@link java.util.Objects}. The replacements have the advantage, that they are properly
30   * annotated with {@link Nullable}, and/or {@link Nonnull}, so they let the
31   * compiler know what their respective results are.
32   *
33   * The various {@code requireNonNull} methods are particularly handy, when
34   * dealing with external code, that a) doesn't support the {@link Nonnull}
35   * annotation, or if you know for other reasons, that an object is non-null.
36   * Take for example, a {@link java.util.Map map}, that you have filled with
37   * non-null values. So, in your opinion, the following should be perfectly
38   * valid code:
39   * <pre>
40   *   final Map&lt;String,Object&gt; map = getMapOfNonNullValues();
41   *   final @Nonnull Object o = map.get("SomeKey");
42   * </pre>
43   * However, if your Java compiler *does* null analysis, it will reject this
44   * example as invalid, because {@link java.util.Map#get(Object)} might return
45   * a null value. As a workaround, you can use this:
46   * <pre>
47   *   import static org.apache.commons.lang3.function.Objects.requireNonNull;
48   *
49   *   final Map&lt;String,Object&gt; map = getMapOfNonNullValues();
50   *   final @Nonnull Object o = requireNonNull(map.get("SomeKey"));
51   * </pre>
52   *
53   * This class is somewhat redundant with regards to {@link ObjectUtils}.
54   * For example, {@link #requireNonNull(Object, Object)} is almost equivalent
55   * with {@link ObjectUtils#defaultIfNull(Object, Object)}. However, it isn't
56   * quite the same, because the latter can, in fact, return null. The former
57   * can't, and the Java compiler confirms this.(An alternative to redundancy
58   * would have been to change the {@code ObjectUtils} class. However, that
59   * would mean loosing upwards compatibility, and we don't do that.)
60   *
61   * @since 3.12.0
62   */
63  public class Objects {
64  
65      /**
66       * Checks, whether the given object is non-null. If so, returns the non-null
67       * object as a result value. Otherwise, a NullPointerException is thrown.
68       * @param <T> The type of parameter {@code value}, also the result type.
69       * @param value The value, which is being checked.
70       * @return The given input value, if it was found to be non-null.
71       * @throws NullPointerException The input value was null.
72       * @see java.util.Objects#requireNonNull(Object)
73       */
74      public static <T> @Nonnull T requireNonNull(@Nullable final T value) throws NullPointerException {
75          return requireNonNull(value, "The value must not be null.");
76      }
77  
78      /**
79       * Checks, whether the given object is non-null. If so, returns the non-null
80       * object as a result value. Otherwise, invokes the given {@link Supplier},
81       * and returns the suppliers result value.
82       * @param <T> The type of parameter {@code value}, also the result type of
83       *    the default value supplier, and of the method itself.
84       * @param <E> The type of exception, that the {@code default value supplier},
85       *    may throw.
86       * @param value The value, which is being checked.
87       * @param defaultValueSupplier The supplier, which returns the default value. This default
88       *   value <em>must</em> be non-null. The supplier will only be invoked, if
89       *   necessary. (If the {@code value} parameter is null, that is.)
90       * @return The given input value, if it was found to be non-null. Otherwise,
91       *   the value, that has been returned by the default value supplier.
92       * @see #requireNonNull(Object)
93       * @see #requireNonNull(Object, String)
94       * @see #requireNonNull(Object, Supplier)
95       * @throws NullPointerException The default value supplier is null, or the default
96       *   value supplier has returned null.
97       */
98      public static <T, E extends Throwable> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final FailableSupplier<T, E> defaultValueSupplier) throws NullPointerException {
99          if (value == null) {
100             final FailableSupplier<T, ?> supplier = requireNonNull(defaultValueSupplier, "The supplier must not be null");
101             final T defaultValue;
102             try {
103                 defaultValue = supplier.get();
104             } catch (final Throwable t) {
105                 throw Failable.rethrow(t);
106             }
107             return requireNonNull(defaultValue, "The supplier must not return null.");
108         }
109         return value;
110     }
111 
112     /**
113      * Checks, whether the given object is non-null. If so, returns the non-null
114      * object as a result value. Otherwise, a NullPointerException is thrown.
115      * @param <T> The type of parameter {@code value}, also the result type.
116      * @param value The value, which is being checked.
117      * @param msg A string, which is being used as the exceptions message, if the
118      *   check fails.
119      * @return The given input value, if it was found to be non-null.
120      * @throws NullPointerException The input value was null.
121      * @see java.util.Objects#requireNonNull(Object, String)
122      * @see #requireNonNull(Object, Supplier)
123      */
124     public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final String msg) throws NullPointerException {
125         if (value == null) {
126             throw new NullPointerException(msg);
127         }
128         return value;
129     }
130 
131     /**
132      * Checks, whether the given object is non-null. If so, returns the non-null
133      * object as a result value. Otherwise, a NullPointerException is thrown.
134      * @param <T> The type of parameter {@code value}, also the result type.
135      * @param value The value, which is being checked.
136      * @param msgSupplier A supplier, which creates the exception message, if the check fails.
137      *     This supplier will only be invoked, if necessary.
138      * @return The given input value, if it was found to be non-null.
139      * @throws NullPointerException The input value was null.
140      * @see java.util.Objects#requireNonNull(Object, String)
141      * @see #requireNonNull(Object, String)
142      */
143     public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final Supplier<String> msgSupplier) throws NullPointerException {
144         if (value == null) {
145             throw new NullPointerException(msgSupplier.get());
146         }
147         return value;
148     }
149 
150     /**
151      * Checks, whether the given object is non-null. If so, returns the non-null
152      * object as a result value. Otherwise, a NullPointerException is thrown.
153      * @param <T> The type of parameter {@code value}, also the result type.
154      * @param value The value, which is being checked.
155      * @param defaultValue The default value, which is being returned, if the
156      *   check fails, and the {@code value} is null.
157      * @throws NullPointerException The input value, and the default value are null.
158      * @return The given input value, if it was found to be non-null.
159      * @see java.util.Objects#requireNonNull(Object)
160      */
161     public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final T defaultValue) throws NullPointerException {
162         return value == null ? requireNonNull(defaultValue) : value;
163     }
164 }