{"record":{"id":"98b3f5cb283ccfaa","repo":"TheAlgorithms/Java","slug":"listener-must-not-be-null-98b3f5","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/LIFOCache.java","lineNumber":533,"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 LIFOCache} instance with the configured parameters.\n         *\n         * @return a fully configured {@code LIFOCache} instance\n         */\n        public LIFOCache<K, V> build() {\n            return new LIFOCache<>(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":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/datastructures/caches/LIFOCache.java#L515-L551","documentation":"Thrown by LIFOCache.Builder.evictionListener(BiConsumer) when the listener is null. The listener fires on every eviction/overwrite; a null would NPE inside put/removeKey rather than at configuration. The guard surfaces the failure at build/configuration time.","triggerScenarios":"builder.evictionListener(null); builder.evictionListener(maybeMetrics) where maybeMetrics is uninitialized; conditional wiring in some environments.","commonSituations":"Feature-flagged metrics off; DI injecting null; tests omitting 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 a required DI dependency."],"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 off.","Make the listener a required DI dependency.","Guard conditional wiring with an explicit null check."],"tags":["java","lifo-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"}