{"record":{"id":"26be153ec5b58681","repo":"TheAlgorithms/Java","slug":"listener-must-not-be-null-26be15","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/RRCache.java","lineNumber":475,"sourceCode":"         */\n        public Builder<K, V> random(Random r) {\n            if (r == null) {\n                throw new IllegalArgumentException(\"Random must not be null\");\n            }\n            this.random = r;\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 RRCache} instance with the configured parameters.\n         *\n         * @return a fully configured {@code RRCache} instance\n         */\n        public RRCache<K, V> build() {\n            return new RRCache<>(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":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/datastructures/caches/RRCache.java#L457-L493","documentation":"Builder.evictionListener() rejects null because it expects a BiConsumer callback for eviction events. If no listener is needed, simply do not call this method — the cache handles a null listener field internally.","triggerScenarios":"Calling builder.evictionListener(null), or passing a listener variable that was never assigned.","commonSituations":"Conditionally wiring a listener and passing null when the condition is false, instead of skipping the call. Passing an uninjected dependency.","solutions":["Do not call evictionListener() if you do not need eviction callbacks","Only call the method inside a conditional that guarantees a non-null listener"],"exampleFix":"// before\nBiConsumer<String,String> listener = enableLogging ? loggingListener : null;\nnew RRCache.Builder<String,String>(100).evictionListener(listener).build();\n\n// after\nRRCache.Builder<String,String> b = new RRCache.Builder<>(100);\nif (enableLogging) b.evictionListener(loggingListener);\nb.build();","handlingStrategy":"validation","validationCode":"// Only call evictionListener() when you have a real callback.\nif (listener != null) {\n    builder.evictionListener(listener);\n}","typeGuard":"if (listener instanceof BiConsumer) {\n    builder.evictionListener((BiConsumer<K,V>) listener);\n}","tryCatchPattern":"try {\n    builder.evictionListener(listener);\n} catch (IllegalArgumentException e) {\n    // listener was null — skip, no callbacks\n}","preventionTips":["Do not call evictionListener() if you do not need callbacks","Guard the call with a null check rather than passing null","Use a no-op BiConsumer if you need a placeholder"],"tags":["rr-cache","null-safety","validation","builder"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}