Organisez comment utiliser les org.Immutables de Java.
Le site officiel est ci-dessous. (Fondamentalement, le contenu de cet article est basé sur cela) https://immutables.github.io/
Définissez la dépendance dans pom.xml de maven.
<dependency>
  <groupId>org.immutables</groupId>
  <artifactId>value</artifactId>
  <version>2.8.2</version>
  <scope>provided</scope>
</dependency>
Créez un objet Immuable en créant une classe Value qui stocke les données et en créant une classe Immuable générée automatiquement à partir de celle-ci. Utilisé lors de la création d'un objet que vous ne souhaitez pas modifier.
Value --Déclarer avec l'annotation immuable.
import java.util.List;
import org.immutables.value.Value.Immutable;
@Immutable
public interface User {
    String name();
    String address();
    int age();
    List<String> hobbies();
}
Builder --Une classe immuable générée automatiquement à partir de la classe Value (classe User dans l'exemple ci-dessus) est utilisée.
        User user = ImmutableUser.builder()
            .name("Tom")
            .age(21)
            .address("Tokyo, Japan")
            .addHobbies("reading", "skiing")
            .build();
        System.out.println(user.toString());
        // User{name=Tom, address=Tokyo, Japan, age=21, hobbies=[reading, skiing]}
        System.out.println(user.name());
        // Tom
        System.out.println(user.age());
        // 21
        //listMap est un objet immuable
        listMap.list().add("item"); // java.lang.UnsupportedOperationException
        listMap.map().put("key", "value"); //java.lang.UnsupportedOperationException
from() --Utilisez la méthode from pour créer un autre objet immuable basé sur un objet immuable.
        User userTemp = ImmutableUser.builder()
            .name("Tom")
            .age(21)
            .address("Tokyo, Japan")
            .addHobbies("reading", "skiing")
            .build();
        User user = ImmutableUser.builder()
            .from(userTemp)
            .address("Osaka, Japan")
            .build();
        System.out.println(user.toString());
        // User{name=Tom, address=Osaka, Japan, age=21, hobbies=[reading, skiing]}
Constructor --Lors de la création d'un objet immuable avec le constructeur, ajoutez l'annotation Parameter à la méthode.
import org.immutables.value.Value.Immutable;
import org.immutables.value.Value.Parameter;
@Immutable
public interface Item {
    @Parameter
    String name();
    @Parameter
    int price();
}
--Créez un objet Immutable en donnant des données à la méthode of de la classe Immutable.
        Item item = ImmutableItem.of("apple", 213);
        System.out.println(item);
        // Item{name=apple, price=213}
Optional
--Utilisez Facultatif lors de la définition d'un élément facultatif dans la classe Immuable.
import java.util.Optional;
import org.immutables.value.Value.Immutable;
@Immutable
public interface Address {
    String country();
    String city();
    String blockNmuber();
    Optional<String> apartmentName();
}
        Address address1=ImmutableAddress.builder()
            .country("Japan")
            .city("Yokohama")
            .blockNmuber("1-2-3")
            .build(); // OK
        Address address2=ImmutableAddress.builder()
            .country("Japan")
            .city("Chiba")
            .blockNmuber("1-2-3")
            .apartmentName("YYY Apartment")
            .build(); // OK
        
        Address address3=ImmutableAddress.builder()
            .country("Japan")
            .city("Chiba")
            .build(); // java.lang.IllegalStateException: Cannot build Address, some of required attributes are not set [blockNmuber]
Default
--Ajoutez l'annotation par défaut à l'élément dont vous voulez avoir la valeur par défaut et définissez la méthode par défaut.
import org.immutables.value.Value.Default;
import org.immutables.value.Value.Immutable;
@Immutable
public interface AddressWithDefault {
    @Default
    default String country(){
        return "Japan";
    }
    String city();
    String blockNmuber();
}
--Si vous ne définissez pas les données lors de la création de l'objet immuable, la valeur par défaut sera définie.
        AddressWithDefault address = ImmutableAddressWithDefault.builder()
            .city("Saitama")
            .blockNmuber("4-5-6")
            .build();
        System.out.println(address.toString());
        // AddressWithDefault{country=Japan, city=Saitama, blockNmuber=4-5-6}
Derived
--Ajoutez l'annotation dérivée et définissez les éléments à traiter en fonction de l'ensemble de données de l'objet immuable.
import java.util.Map;
import org.immutables.value.Value.Derived;
import org.immutables.value.Value.Immutable;
@Immutable
public abstract class Receipt {
    abstract Map<String, Integer> items();
    @Derived
    public int total() {
        //Additionner les valeurs des éléments
        return items().values().stream().reduce(0, Integer::sum);
    }
}
       Receipt receipt = ImmutableReceipt.builder()
            .putItems("bread", 210)
            .putItems("milk", 100)
            .build();
        System.out.println(receipt.total());
        // 310
Precondition check
--Définissez le processus de vérification lorsqu'un objet immuable est créé avec l'annotation Vérifier.
import java.util.List;
import org.immutables.value.Value.Check;
import org.immutables.value.Value.Immutable;
@Immutable
public abstract class Cart {
    abstract List<String> items();
    @Check
    protected void check() {
        if (items() == null || items().isEmpty()) {
            throw new IllegalStateException();
        }
    }
}
--Si les conditions de vérification ne sont pas remplies, une erreur peut être générée lors de la création d'un objet immuable.
        ImmutableCart.builder().build(); // java.lang.IllegalStateException
Wrapper Types
Si vous avez une interface Wrapped et une classe Wrapper, la définition de la classe Value sera simple et vous n'aurez pas à écrire du code similaire encore et encore.
Interface enveloppée
    @Value.Style(
            typeAbstract = "_*",
            typeImmutable = "*",
            visibility = ImplementationVisibility.PUBLIC,
            defaults = @Value.Immutable(builder = false, copy = false))
    public @interface Wrapped {
    }
    public static abstract class Wrapper<T> {
        @Value.Parameter
        public abstract T value();
        @Override
        public String toString() {
            return getClass().getSimpleName() + "(" + value() + ")";
        }
    }
--La classe Value et comment l'appeler sont les suivantes.
    @Value.Immutable
    @Wrapped
    public static abstract class _FirstName extends Wrapper<String> {
    }
    @Value.Immutable
    @Wrapped
    public static abstract class _LastName extends Wrapper<String> {
    }
    @Value.Immutable
    @Wrapped
    public static abstract class _Age extends Wrapper<Integer> {
    }
    FirstName firstName = FirstName.of("Taro");
    LastName lastName = LastName.of("Yamada");
    Age age = Age.of(45);
--Nettoyez puis compilez, comme mvn clean compile.
--Définissez false dans l'option useIncrementalCompilation.
- https://immutables.github.io/getstarted.html#troubleshooting
Recommended Posts