{"record":{"id":"a9bca851241e1285","repo":"TheAlgorithms/Java","slug":"listener-must-not-be-null","errorCode":null,"errorMessage":"Listener must not be null","messagePattern":"Listener must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java","lineNumber":519,"sourceCode":"         */\n        public Builder<K, V> defaultTTL(long ttlMillis) {\n            if (ttlMillis < 0) {\n                throw new IllegalArgumentException(\"Default TTL must be >= 0\");\n            }\n            this.defaultTTL = ttlMillis;\n            return this;\n        }\n\n        /**\n         * Sets an eviction listener to be notified when entries are evicted from the cache.\n         *\n         * @param listener a {@link BiConsumer} that accepts evicted keys and values; must not be {@code null}\n         * @return this builder instance for chaining\n         * @throws IllegalArgumentException if {@code listener} is {@code null}\n         */\n        public Builder<K, V> evictionListener(BiConsumer<K, V> listener) {\n            if (listener == null) {\n                throw new IllegalArgumentException(\"Listener must not be null\");\n            }\n            this.evictionListener = listener;\n            return this;\n        }\n\n        /**\n         * Builds and returns a new {@link FIFOCache} instance with the configured parameters.\n         *\n         * @return a fully configured {@code FIFOCache} instance\n         */\n        public FIFOCache<K, V> build() {\n            return new FIFOCache<>(this);\n        }\n\n        /**\n         * Sets the eviction strategy used to determine when to clean up expired entries.\n         *\n         * @param strategy an {@link EvictionStrategy} implementation; must not be {@code null}","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/datastructures/caches/FIFOCache.java#L501-L537","documentation":"Thrown by FIFOCache.Builder.evictionListener(BiConsumer) when the listener is null. The listener is invoked on every eviction/overwrite, and a null listener would cause an NPE deep inside put/removeKey rather than at the configuration site. The guard ensures the failure surfaces at configuration time.","triggerScenarios":"builder.evictionListener(null); builder.evictionListener(metricsRegistrar) where metricsRegistrar was never initialized; conditional wiring where the listener is only set in some environments.","commonSituations":"Feature-flagged metrics where the flag is off; DI misconfiguration that injects null; test builders that omit the listener.","solutions":["Provide a no-op listener instead of null: (k,v) -> {}.","Guard the wiring: if (listener != null) builder.evictionListener(listener);","Make the listener field required in your DI configuration so null cannot be injected."],"exampleFix":"// before\nbuilder.evictionListener(maybeListener);\n// after\nbuilder.evictionListener(maybeListener != null ? maybeListener : (k, v) -> {});","handlingStrategy":"validation","validationCode":"BiConsumer<K, V> listener = maybeListener != null ? maybeListener : (k, v) -> {};\nbuilder.evictionListener(listener);","typeGuard":"static <K, V> boolean isUsableListener(BiConsumer<K, V> listener) {\n    return listener != null;\n}","tryCatchPattern":null,"preventionTips":["Provide a no-op listener rather than null when metrics are disabled.","Make the listener a required DI dependency so null cannot be injected.","Guard conditional wiring with an explicit null check."],"tags":["java","fifo-cache","builder","null-check","argument-validation","cache"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}