web-dev-qa-db-fra.com

Est-ce que Java 14 enregistrements économisent en fait de la mémoire sur une déclaration de classe similaire ou sont-ils plutôt du sucre syntaxique?

J'espère que Java 14 enregistrements utilisent en fait moins de mémoire qu'une classe de données similaire.

Est-ce qu'ils utilisent la mémoire ou sont-ils les mêmes?

9
Clancy Merrick

J'ai fait des tests rapides et sales avec la suite

public record PersonRecord(String firstName, String lastName) {}

vs.

import Java.util.Objects;

public final class PersonClass {
    private final String firstName;
    private final String lastName;

    public PersonClass(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String firstName() {
        return firstName;
    }

    public String lastName() {
        return lastName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PersonClass that = (PersonClass) o;
        return firstName.equals(that.firstName) &&
                lastName.equals(that.lastName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(firstName, lastName);
    }

    @Override
    public String toString() {
        return "PersonRecord[" +
                "firstName=" + firstName +
                ", lastName=" + lastName +
                "]";
    }
}

Le fichier d'enregistrement compilé s'élève à 1,475 octets, la classe à 1,643 octets. La différence de taille provient probablement de différentes implémentations equals/toString/hashCode.

Peut-être que quelqu'un peut creuser un bytecode ...

1
lugiorgi

correct, je suis d'accord avec [@lugiorgi] et [@Naman], la seule différence dans le bytecode généré entre un enregistrement et la classe équivalente réside dans l'implémentation des méthodes: toString, equals et hashCode. Qui, dans le cas d'une classe d'enregistrement, sont implémentés en utilisant une instruction invoke dynamic (indy) à la même méthode bootstrap à la classe: Java.lang.runtime.ObjectMethods (fraîchement ajouté dans le projet records). Le fait que ces trois méthodes, toString, equals et hashCode, invoquent la même méthode bootstrap économise plus d'espace dans le fichier de classe que en invoquant 3 méthodes de bootstraps différentes. Et bien sûr, comme déjà montré dans les autres réponses, économise plus d'espace que la génération du bytecode évident

1
Vicente Romero