Why is Objects.requireNonNull automatically added by javac

150 views Asked by At

I have a code that prints some metadata information from cosmos, and I want to print it in case that the response is not null, if it's, it's not important, and just log a null entry

Java File:

 private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {
        @Override
        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            if (responseDiagnostics != null && log.isDebugEnabled()) {
                CosmosDiagnostics cosmosResponseDiagnostics = responseDiagnostics.getCosmosDiagnostics();
                Duration latency = tryGet(cosmosResponseDiagnostics::getDuration);
                log.debug("action=CosmosQueryLatencyInMs, value={}", tryGet(latency::toMillis));
            }
        }
    }

The tryGet function just makes sure that if any invocation throws an exception it will return a null

 /***
     * try to get a value with optional null on error
     * @param supplier object supplier
     * @return returns T type
     */
    static <T> T tryGet(Supplier<T> supplier) {
        return tryGet(supplier, null);
    }


    /***
     * try to get a value with optional default on null
     * @param supplier object supplier
     * @param defaultValue defaultValue
     * @return returns T type
     */
    static <T> T tryGet(Supplier<T> supplier, T defaultValue) {
        try {
            T result = supplier.get();
            if (result == null) {
                return defaultValue;
            }
            return result;
        } catch (Exception e) {
            //ignore
            // this is to get value with null propagation
            return defaultValue;
        }
    }

But unfortunately the generated code adds Objects.requireNonNull, which defeats the whole purpose of the tryGet to stop the null propagation

Compiled .Class File:

 private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {
        private ResponseDiagnosticsProcessorImplementation() {
        }

        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            if (responseDiagnostics != null && CosmosDbConfiguration.log.isDebugEnabled()) {
                CosmosDiagnostics cosmosResponseDiagnostics = responseDiagnostics.getCosmosDiagnostics();
                Objects.requireNonNull(cosmosResponseDiagnostics);
                Duration latency = (Duration)ValueSupplierUtil.tryGet(cosmosResponseDiagnostics::getDuration);
                Logger var10000 = CosmosDbConfiguration.log;
                Objects.requireNonNull(latency);
                var10000.debug("action=CosmosQueryLatencyInMs, value={}", ValueSupplierUtil.tryGet(latency::toMillis));
            }

        }
    }

I can simply change the code so that the try get evaluates the whole expression so that it doesn't propagate the null pointer exception

Java File:

private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {
        @Override
        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            if (responseDiagnostics != null && log.isDebugEnabled()) {
                log.debug("action=CosmosQueryLatencyInMs, value={}",
                        tryGet(() -> responseDiagnostics.getCosmosDiagnostics().getDuration().toMillis()));
            }
        }
    }

And that keeps the same behaviour in the class code:

Compiled .Class File:

private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {
        private ResponseDiagnosticsProcessorImplementation() {
        }

        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            if (responseDiagnostics != null && CosmosDbConfiguration.log.isDebugEnabled()) {
                CosmosDbConfiguration.log.debug("action=CosmosQueryLatencyInMs, value={}", ValueSupplierUtil.tryGet(() -> {
                    return responseDiagnostics.getCosmosDiagnostics().getDuration().toMillis();
                }));
            }

        }
    }

My question is, in which cases the Java Compiler adds a requires non null check and why?

0

There are 0 answers