RandomWits

life is too short for a diary




Daily Logs for Sep 16, 2026

Tags: java letters sonar

Author
Written by: Tushar Sharma

Dear Vishi, dear logs for today.

Sonar

SONARJAVA-6714 is a SonarJava Bug ticket.

what's sonarjava? SonarJava is static code analyzer for Java.

For Sonar Java versiosn 8.38.0.46176, it's listed under False positive as

S2638 should not raise on type argumets when overriding a method with @nullable return type form a @NullMarked class

what's S2638? It's an identifier for specific Java rule : Method overrides should not change contracts.

e.g

interface UserService {
    @NonNull
    String findName();
}

class UserServiceImpl implements UserService {
    @Override
    @Nullable
    public String findName() {
        return null;
    }
}

SonarJava raises S2638 because the interface promises that the method findName never return null, but the implementations weakens the promise by allowing null. Another example

interface UserService {
    void save(@Nullable String name);
}

class UserServiceImpl implements UserService {
    @Override
    public void save(@NonNull String name) {
    }
}

The interface says callers may pass null, but the implementation refuses it.

With Lombok Annotation

A record is a class with immutable fields. So we dont have traditional setters methods. However we can use wither function which can return a new object. In short, it's a immutable setter.

Lets start with two java records

public record Users (
    UUID id, 
    String name
) {}

public record usersWith(UUID id, String name) {}

First compile the Java classes in gradle

./gradlew compileJava

Then lets analyze this

javap -classpath build/classes/java/main com.example.model.Users

public final class com.example.model.Users extends java.lang.Record {

    public com.example.model.Users(java.util.UUD, java.lang.String);  //constructor

    public final java.lang.String toString(); 

    public final int hashCode(); 

    public final boolean equals(java.lang.Object); 

    public java.util.UUID id();

    public java.lang.String name(); 
    }

And for UsersWith

javap -classpath build/classes/java/main com.example.model.UsersWith

public final class com.example.model.UsersWith extends java.lang.Record {

    public com.example.model.UsersWith(java.util.UUD, java.lang.String);  //constructor


    public com.example.model.UsersWith withId(java.util.UUID); 

    public com.example.model.UsersWith withName(java.util.UUID); 

    public final java.lang.String toString(); 

    public final int hashCode(); 

    public final boolean equals(java.lang.Object); 

    public java.util.UUID id();

    public java.lang.String name(); 
}

comments powered by Disqus