Guide pour la création d’objets en Java

Guide de création d'objets en Java

1. Vue d'ensemble

Autrement dit, avant de pouvoir utiliser un objet sur la machine virtuelle, il doit être initialisé.

Dans les sections suivantes, nous examinerons différentes manières d'initialiser des types et des objets primitifs.

2. Déclaration vs. Initialisation

Commençons par nous assurer que nous sommes sur la même longueur d'onde.

Declaration is the process of defining the variable avec son type et son nom.

Ici, nous déclarons la variableid:

int id;

L'initialisation, en revanche, consiste à attribuer une valeur; par exemple:

id = 1;

Pour démontrer, nous allons créer une classeUser avec des propriétésname etid:

public class User implements {
    private String name;
    private int id;

    // standard constructor, getters, setters,
}

Ensuite, nous verrons que l’initialisation fonctionne différemment selon le type de champ que nous initialisons.

3. Objets vs. Primitives

Java fournit deux types de représentation de données: les types primitifs et les types de référence. Dans cette section, nous aborderons les différences entre les deux en ce qui concerne l’initialisation.

Java comporte huit types de données intégrés, appelés types primitifs Java; les variables de ce type tiennent directement leurs valeurs.

Les types de référence contiennent des références à des objets (instances de classes). Unlike primitive types that hold their values in the memory where the variable is allocated, references don’t hold the value of the object they refer to.

Au lieu de cela,a reference points to an object by storing the memory address where the object is located.

Notez que Java ne nous permet pas de découvrir l’adresse de la mémoire physique. Au contraire, nous ne pouvons utiliser la référence que pour faire référence à l'objet.

Jetons un œil à un exemple qui déclare et initialise un type de référence en dehors de notre classeUser:

@Test
public void whenIntializedWithNew_thenInstanceIsNotNull() {
    User user = new User();

    assertThat(user).isNotNull();
}

Comme nous pouvons le voir ici, une référence peut être affectée à un nouveau en utilisant le mot-clénew, qui est responsable de la création du nouvel objetUser.

Continuons à en apprendre davantage sur la création d’objets.

5. Création d'objets

Contrairement aux primitives, la création d'objets est un peu plus complexe. En effet, nous n’ajoutons pas simplement de la valeur au champ; à la place, nous déclenchons l'initialisation à l'aide du mot-clénew. Ceci, en retour, appelle un constructeur et initialise l'objet en mémoire.

Parlons plus en détail des constructeurs et du mot-clénew.

Le mot clénew estresponsible for allocating memory for the new object through a constructor.

A constructor is typically used to initialize instance variables representing the main properties of the created object.

Si nous ne fournissons pas un constructeur explicitement, le compilateur créera un constructeur par défaut qui n'a pas d'arguments et alloue juste de la mémoire pour l'objet.

A class can have many constructors as long as their parameters lists are different (overload). Chaque constructeur qui n'appelle pas un autre constructeur dans la même classe a un appel à son constructeur parent, qu'il ait été écrit explicitement ou inséré par le compilateur viasuper().

Ajoutons un constructeur à notre classeUser:

public User(String name, int id) {
    this.name = name;
    this.id = id;
}

Nous pouvons maintenant utiliser notre constructeur pour créer un objetUser avec des valeurs initiales pour ses propriétés:

User user = new User("Alice", 1);

6. Portée Variable

Dans les sections suivantes, nous examinerons les différents types d'étendues dans lesquelles une variable Java peut exister et comment cela affecte le processus d'initialisation.

6.1. Variables d'instance et de classe

Instance and class variables don’t require us to initialize them. Dès que nous déclarons ces variables, elles reçoivent une valeur par défaut comme suit:

image

Maintenant, essayons de définir des variables relatives aux instances et aux classes et testons si elles ont une valeur par défaut ou non:

@Test
public void whenValuesAreNotInitialized_thenUserNameAndIdReturnDefault() {
    User user = new User();

    assertThat(user.getName()).isNull();
    assertThat(user.getId() == 0);
}

6.2. Variables locales

Local variables must be initialized before use, car ils n'ont pas de valeur par défaut et le compilateur ne nous laissera pas utiliser une valeur non initialisée.

Par exemple, le code suivant génère une erreur de compilation:

public void print(){
    int i;
    System.out.println(i);
}

7. Le mot-cléFinal

Le mot cléfinal appliqué à un champ signifie que la valeur du champ ne peut plus être modifiée après l'initialisation. De cette façon, nous pouvons définir des constantes en Java.

Ajoutons une constante à notre classeUser:

private static final int YEAR = 2000;

Les constantes doivent être initialisées lors de leur déclaration ou dans un constructeur.

8. Initialiseurs en Java

En Java, uninitializer is a block of code that has no associated name or data type et est placé en dehors de toute méthode, constructeur ou autre bloc de code.

Java propose deux types d'initialiseurs, les initialiseurs statiques et d'instance. Voyons comment nous pouvons utiliser chacun d’eux.

8.1. Initialiseurs d'instance

Nous pouvons les utiliser pour initialiser les variables d'instance.

Pour démontrer, fournissons une valeur pour un utilisateurid à l'aide d'un initialiseur d'instance dans notre classeUser:

{
    id = 0;
}

8.2. Bloc d'initialisation statique

Un initialiseur statique ou un bloc statique - est un bloc de code qui est utilisé pour initialiser les champsstatic. En d'autres termes, il s'agit d'un simple initialiseur marqué du mot cléstatic:

private static String forum;
static {
    forum = "Java";
}

9. Ordre d'initialisation

Lorsque vous écrivez un code qui initialise différents types de champs, vous devez bien sûr garder un œil sur l’ordre d’initialisation.

En Java, l'ordre des instructions d'initialisation est le suivant:

  • variables statiques et initialiseurs statiques dans l'ordre

  • variables d'instance et initialiseurs d'instance dans l'ordre

  • constructeurs

10. Cycle de vie des objets

Maintenant que nous avons appris à déclarer et initialiser des objets, découvrons ce qui arrive aux objets lorsqu'ils ne sont pas utilisés.

Contrairement aux autres langages où nous devons nous préoccuper de la destruction d’objets, Java s’occupe des objets obsolètes via son ramasse-miettes.

All objects in Java are stored in our program’s heap memory. En fait, le segment de mémoire représente un grand pool de mémoire inutilisée, allouée à notre application Java.

D'autre part, lesgarbage collector is a Java program that takes care of automatic memory management en supprimant les objets qui ne sont plus accessibles.

Pour qu'un objet Java devienne inaccessible, il doit rencontrer l'une des situations suivantes:

  • L'objet n'a plus aucune référence pointant vers lui

  • Toutes les références pointant sur l'objet sont hors de portée

En conclusion, un objet est d'abord créé à partir d'une classe, généralement en utilisant le mot-clénew. Ensuite, l'objet vit sa vie et nous donne accès à ses méthodes et champs.

Enfin, lorsqu'il n'est plus nécessaire, le garbage collector le détruit.

11. Autres méthodes de création d'objets

Dans cette section, nous examinerons brièvementmethods other than new keyword to create objects and how to apply them, specifically reflection, cloning, and serialization.

Reflection is a mechanism we can use to inspect classes, fields, and methods at run-time. Voici un exemple de création de notre objetUser à l'aide de la réflexion:

@Test
public void whenInitializedWithReflection_thenInstanceIsNotNull()
  throws Exception {
    User user = User.class.getConstructor(String.class, int.class)
      .newInstance("Alice", 2);

    assertThat(user).isNotNull();
}

Dans ce cas, nous utilisons la réflexion pour rechercher et appeler un constructeur de la classeUser.

La méthode suivante,cloning, is a way to create an exact copy of an object. Pour cela, notre classeUser doit implémenter l'interfaceCloneable:

public class User implements Cloneable { //... }

Maintenant, nous pouvons utiliser la méthodeclone() pour créer un nouvel objetclonedUser qui a les mêmes valeurs de propriété que l'objetuser:

@Test
public void whenCopiedWithClone_thenExactMatchIsCreated()
  throws CloneNotSupportedException {
    User user = new User("Alice", 3);
    User clonedUser = (User) user.clone();

    assertThat(clonedUser).isEqualTo(user);
}

Nous pouvons également utiliser la classesun.misc.Unsafe pour allouer de la mémoire à un objet sans appeler de constructeur:

User u = (User) unsafeInstance.allocateInstance(User.class);

12. Conclusion

Dans ce tutoriel, nous avons abordé l’initialisation des champs en Java. Nous avons découvert différents types de données en Java et comment les utiliser. Nous avons également approfondi plusieurs manières de créer des objets en Java.

L'implémentation complète de ce tutoriel peut être trouvéeover on Github.