or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

builder-pattern.mdconstructors.mddata-classes.mdexperimental.mdimmutable-patterns.mdindex.mdlogging.mdobject-methods.mdproperty-access.mdtype-inference.mdutilities.md
tile.json

data-classes.mddocs/

Data Classes

Comprehensive data class support with automatic generation of getters, setters, constructors, and object methods. The @Data and @Value annotations provide complete data class functionality with minimal boilerplate.

Capabilities

@Data Annotation

Generates a complete mutable data class with getters, setters, constructors, toString, equals, and hashCode methods.

/**
 * Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
 * all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor
 * (except that no constructor will be generated if any explicitly written constructors already exist).
 * 
 * Equivalent to @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
    /**
     * If you specify a static constructor name, then the generated constructor will be private, and
     * instead a static factory method is created that other classes can use to create instances.
     * We suggest the name: "of", like so:
     * 
     * public @Data(staticConstructor = "of") class Point { final int x, y; }
     * 
     * Default: No static constructor, instead the normal constructor is public.
     * 
     * @return Name of static 'constructor' method to generate (blank = generate a normal constructor).
     */
    String staticConstructor() default "";
}

Usage Examples:

import lombok.Data;

@Data
public class Person {
    private final String name;
    private int age;
    private String email;
}

// Generated methods available:
// - String getName()
// - int getAge()
// - void setAge(int age) 
// - String getEmail()
// - void setEmail(String email)
// - Person(String name)  // Required args constructor
// - String toString()
// - boolean equals(Object o)
// - int hashCode()

// Usage
Person person = new Person("John Doe");
person.setAge(30);
person.setEmail("john@example.com");
System.out.println(person.toString()); // Person(name=John Doe, age=30, email=john@example.com)

With Static Constructor:

@Data(staticConstructor = "of")
public class Point {
    private final int x;
    private final int y;
}

// Usage
Point point = Point.of(10, 20);

@Value Annotation

Generates an immutable value class with all fields final, getters, all-args constructor, toString, equals, and hashCode methods.

/**
 * Generates immutable value objects. Makes all fields private and final, generates getters,
 * all-args constructor, toString, equals, and hashCode methods.
 * 
 * Equivalent to @Getter @FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) 
 * @AllArgsConstructor @ToString @EqualsAndHashCode.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Value {
    /**
     * If you specify a static constructor name, then the generated constructor will be private, and
     * instead a static factory method is created that other classes can use to create instances.
     * 
     * @return Name of static 'constructor' method to generate (blank = generate a normal constructor).
     */
    String staticConstructor() default "";
}

Usage Examples:

import lombok.Value;

@Value
public class Address {
    String street;
    String city;
    String zipCode;
}

// Generated methods available:
// - String getStreet()
// - String getCity() 
// - String getZipCode()
// - Address(String street, String city, String zipCode)  // All args constructor
// - String toString()
// - boolean equals(Object o)
// - int hashCode()

// Usage
Address address = new Address("123 Main St", "Anytown", "12345");
System.out.println(address.getStreet()); // 123 Main St
// address.street = "new street"; // Compilation error - field is final

With Static Constructor:

@Value(staticConstructor = "of")
public class Coordinates {
    double latitude;
    double longitude;
}

// Usage
Coordinates coords = Coordinates.of(40.7128, -74.0060);

Advanced Usage

Combining with Other Annotations

import lombok.Value;
import lombok.Builder;
import lombok.extern.slf4j.Slf4j;

@Value
@Builder
@Slf4j
public class ImmutableUser {
    String username;
    String email;
    int age;
    
    public void logInfo() {
        log.info("User: {} ({})", username, email);
    }
}

// Usage with builder
ImmutableUser user = ImmutableUser.builder()
    .username("johndoe")
    .email("john@example.com")
    .age(30)
    .build();

Inheritance Considerations

@Data
public class Animal {
    private final String species;
    private String name;
}

@Data(callSuper = true)  // Note: This parameter doesn't exist on @Data
// Use @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) instead
public class Dog extends Animal {
    private String breed;
    
    public Dog(String species, String breed) {
        super(species);
        this.breed = breed;
    }
}

Generated Code Behavior

@Data Generated Code Pattern

For a @Data class with fields:

  • Getters: Generated for all fields
  • Setters: Generated for all non-final fields
  • Constructor: Required arguments constructor (final fields and @NonNull fields)
  • toString(): Includes all fields
  • equals()/hashCode(): Based on all non-transient fields

@Value Generated Code Pattern

For a @Value class with fields:

  • Getters: Generated for all fields
  • No Setters: All fields are final
  • Constructor: All arguments constructor
  • toString(): Includes all fields
  • equals()/hashCode(): Based on all fields

Configuration

Both annotations respect lombok configuration settings:

  • lombok.data.flagUsage: Control usage warnings
  • lombok.value.flagUsage: Control usage warnings
  • lombok.toString.includeFieldNames: Default field name inclusion
  • lombok.equalsAndHashCode.doNotUseGetters: Use fields directly