aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/org/apache/commons/lang3/function/Objects.java
blob: f07a0edbd9b609ace1f4b154ed031f8cf5bf2f32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.lang3.function;

import java.util.function.Supplier;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.apache.commons.lang3.ObjectUtils;

/**
 * This class provides some replacements for the corresponding methods in
 * {@link java.util.Objects}. The replacements have the advantage, that they are properly
 * annotated with {@link Nullable}, and/or {@link Nonnull}, so they let the
 * compiler know what their respective results are.
 *
 * The various {@code requireNonNull} methods are particularly handy, when
 * dealing with external code, that a) doesn't support the {@link Nonnull}
 * annotation, or if you know for other reasons, that an object is non-null.
 * Take for example, a {@link java.util.Map map}, that you have filled with
 * non-null values. So, in your opinion, the following should be perfectly
 * valid code:
 * <pre>
 *   final Map&lt;String,Object&gt; map = getMapOfNonNullValues();
 *   final @Nonnull Object o = map.get("SomeKey");
 * </pre>
 * However, if your Java compiler *does* null analysis, it will reject this
 * example as invalid, because {@link java.util.Map#get(Object)} might return
 * a null value. As a workaround, you can use this:
 * <pre>
 *   import static org.apache.commons.lang3.function.Objects.requireNonNull;
 *
 *   final Map&lt;String,Object&gt; map = getMapOfNonNullValues();
 *   final @Nonnull Object o = requireNonNull(map.get("SomeKey"));
 * </pre>
 *
 * This class is somewhat redundant with regards to {@link ObjectUtils}.
 * For example, {@link #requireNonNull(Object, Object)} is almost equivalent
 * with {@link ObjectUtils#defaultIfNull(Object, Object)}. However, it isn't
 * quite the same, because the latter can, in fact, return null. The former
 * can't, and the Java compiler confirms this.(An alternative to redundancy
 * would have been to change the {@code ObjectUtils} class. However, that
 * would mean loosing upwards compatibility, and we don't do that.)
 *
 * @since 3.12.0
 */
public class Objects {

    /**
     * Checks, whether the given object is non-null. If so, returns the non-null
     * object as a result value. Otherwise, a NullPointerException is thrown.
     * @param <T> The type of parameter {@code value}, also the result type.
     * @param value The value, which is being checked.
     * @return The given input value, if it was found to be non-null.
     * @throws NullPointerException The input value was null.
     * @see java.util.Objects#requireNonNull(Object)
     */
    public static <T> @Nonnull T requireNonNull(@Nullable final T value) throws NullPointerException {
        return requireNonNull(value, "The value must not be null.");
    }

    /**
     * Checks, whether the given object is non-null. If so, returns the non-null
     * object as a result value. Otherwise, invokes the given {@link Supplier},
     * and returns the suppliers result value.
     * @param <T> The type of parameter {@code value}, also the result type of
     *    the default value supplier, and of the method itself.
     * @param <E> The type of exception, that the {@code default value supplier},
     *    may throw.
     * @param value The value, which is being checked.
     * @param defaultValueSupplier The supplier, which returns the default value. This default
     *   value <em>must</em> be non-null. The supplier will only be invoked, if
     *   necessary. (If the {@code value} parameter is null, that is.)
     * @return The given input value, if it was found to be non-null. Otherwise,
     *   the value, that has been returned by the default value supplier.
     * @see #requireNonNull(Object)
     * @see #requireNonNull(Object, String)
     * @see #requireNonNull(Object, Supplier)
     * @throws NullPointerException The default value supplier is null, or the default
     *   value supplier has returned null.
     */
    public static <T, E extends Throwable> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final FailableSupplier<T, E> defaultValueSupplier) throws NullPointerException {
        if (value == null) {
            final FailableSupplier<T, ?> supplier = requireNonNull(defaultValueSupplier, "The supplier must not be null");
            final T defaultValue;
            try {
                defaultValue = supplier.get();
            } catch (final Throwable t) {
                throw Failable.rethrow(t);
            }
            return requireNonNull(defaultValue, "The supplier must not return null.");
        }
        return value;
    }

    /**
     * Checks, whether the given object is non-null. If so, returns the non-null
     * object as a result value. Otherwise, a NullPointerException is thrown.
     * @param <T> The type of parameter {@code value}, also the result type.
     * @param value The value, which is being checked.
     * @param msg A string, which is being used as the exceptions message, if the
     *   check fails.
     * @return The given input value, if it was found to be non-null.
     * @throws NullPointerException The input value was null.
     * @see java.util.Objects#requireNonNull(Object, String)
     * @see #requireNonNull(Object, Supplier)
     */
    public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final String msg) throws NullPointerException {
        if (value == null) {
            throw new NullPointerException(msg);
        }
        return value;
    }

    /**
     * Checks, whether the given object is non-null. If so, returns the non-null
     * object as a result value. Otherwise, a NullPointerException is thrown.
     * @param <T> The type of parameter {@code value}, also the result type.
     * @param value The value, which is being checked.
     * @param msgSupplier A supplier, which creates the exception message, if the check fails.
     *     This supplier will only be invoked, if necessary.
     * @return The given input value, if it was found to be non-null.
     * @throws NullPointerException The input value was null.
     * @see java.util.Objects#requireNonNull(Object, String)
     * @see #requireNonNull(Object, String)
     */
    public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final Supplier<String> msgSupplier) throws NullPointerException {
        if (value == null) {
            throw new NullPointerException(msgSupplier.get());
        }
        return value;
    }

    /**
     * Checks, whether the given object is non-null. If so, returns the non-null
     * object as a result value. Otherwise, a NullPointerException is thrown.
     * @param <T> The type of parameter {@code value}, also the result type.
     * @param value The value, which is being checked.
     * @param defaultValue The default value, which is being returned, if the
     *   check fails, and the {@code value} is null.
     * @throws NullPointerException The input value, and the default value are null.
     * @return The given input value, if it was found to be non-null.
     * @see java.util.Objects#requireNonNull(Object)
     */
    public static <T> @Nonnull T requireNonNull(@Nullable final T value, @Nonnull final T defaultValue) throws NullPointerException {
        return value == null ? requireNonNull(defaultValue) : value;
    }
}