208 votes

Créer un tableau d'objets en Java

Je suis novice en Java et j'ai créé pour la première fois un tableau d'objets en Java.

J'ai une classe A par exemple -

A[] arr = new A[4];

Mais cela ne fait que créer des pointeurs (références) vers A et non pas 4 objets. Est-ce correct ? Je constate que lorsque j'essaie d'accéder aux fonctions/variables des objets créés, j'obtiens une exception de pointeur nul. Pour pouvoir manipuler/accéder aux objets, j'ai dû faire ceci :

A[] arr = new A[4];
for (int i = 0; i < 4; i++) {
    arr[i] = new A();
}

Est-ce correct ou est-ce que je fais quelque chose de mal ? Si c'est correct, c'est vraiment étrange.

EDIT : Je trouve cela étrange car en C++ on dit simplement new A[4] et il crée les quatre objets.

18 votes

Je voulais juste dire que cette question était exceptionnellement utile ; merci de l'avoir posée.

271voto

MeBigFatGuy Points 12489

C'est exact.

A[] a = new A[4];

...crée 4 A des références, comme pour faire ceci :

A a1;
A a2;
A a3;
A a4;

Maintenant, vous ne pourriez pas faire a1.someMethod() sans allouer a1 comme ça :

a1 = new A();

De même, avec le tableau, vous devez faire ceci :

a[0] = new A();

...avant de l'utiliser.

11 votes

Cette réponse m'a épargné un tas de confusion, merci pour son existence.

1 votes

J'ai également eu cette confusion, puisque je viens du milieu C++, j'ai toujours supposé que, comme dans le C++, la méthode Java new Le mot-clé appelle également le constructeur et alloue la mémoire I. Je suppose qu'en Java new ne crée que les références et non l'objet réel, contrairement au C++. Merci pour la réponse.

1 votes

@Krishna_Oza, il n'y a pas de différence avec C++ ici. Le premier new crée un objet tableau. Il s'agit d'objets alloués dynamiquement ("heap"). Le code C++ analogue serait donc A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); } .

83voto

Steve B. Points 23227

C'est correct. Vous pouvez également faire :

A[] a = new A[] { new A("args"), new A("other args"), .. };

Cette syntaxe peut également être utilisée pour créer et initialiser un tableau n'importe où, par exemple dans un argument de méthode :

someMethod( new A[] { new A("args"), new A("other args"), . . } )

38voto

Vamsi Sangam Points 651

Oui, il ne crée que des références, qui sont définies à leur valeur par défaut null. C'est pourquoi vous obtenez une NullPointerException Vous devez créer les objets séparément et attribuer la référence. Il y a 3 étapes pour créer des tableaux en Java : - la création d'un tableau.

Déclaration - Dans cette étape, nous spécifions le type de données et les dimensions du tableau que nous allons créer. Mais souvenez-vous, nous ne mentionnons pas encore les tailles des dimensions. Elles sont laissées vides.

Instanciation - Dans cette étape, nous créons le tableau, ou allouons de la mémoire pour le tableau, en utilisant le mot clé new. C'est à cette étape que nous mentionnons les tailles des dimensions du tableau.

Initialisation - Le tableau est toujours initialisé à la valeur par défaut du type de données. Mais nous pouvons faire nos propres initialisations.

Déclarer des tableaux en Java

Voici comment on déclare un tableau unidimensionnel en Java -.

int[] array;
int array[];

Oracle vous recommande d'utiliser l'ancienne syntaxe pour déclarer les tableaux. Voici quelques autres exemples de déclarations légales -

// One Dimensional Arrays
int[] intArray;             // Good
double[] doubleArray;

// One Dimensional Arrays
byte byteArray[];           // Ugly!
long longArray[];

// Two Dimensional Arrays
int[][] int2DArray;         // Good
double[][] double2DArray;

// Two Dimensional Arrays
byte[] byte2DArray[];       // Ugly
long[] long2DArray[];

Et ce sont quelques exemples de déclarations illégales -

int[5] intArray;       // Don't mention size!
double{} doubleArray;  // Square Brackets please!

Instanciation

C'est ainsi que l'on "instancie", ou que l'on alloue de la mémoire pour un tableau -

int[] array = new int[5];

Lorsque la JVM rencontre le new le mot-clé, il comprend qu'il doit allouer de la mémoire pour quelque chose. Et en spécifiant int[5] nous voulons dire que nous voulons un tableau de int s, de taille 5. Ainsi, la JVM crée la mémoire et assigne la référence de la mémoire nouvellement allouée à array qui est une "référence" de type int[]

Initialisation

Utilisation d'une boucle - L'utilisation d'une boucle for pour initialiser les éléments d'un tableau est la façon la plus courante de faire fonctionner le tableau. Il n'est pas nécessaire d'exécuter une boucle for si vous comptez attribuer la valeur par défaut elle-même, car la JVM le fait pour vous.

Tout en un ! - Nous pouvons déclarer, instancier et initialiser notre tableau en une seule fois. Voici la syntaxe -

int[] arr = {1, 2, 3, 4, 5};

Ici, nous ne mentionnons pas la taille, car la JVM peut voir que nous donnons 5 valeurs.

Donc, jusqu'à ce que nous instanciions les références restent nulles. J'espère que ma réponse vous a aidé ! :)

Source - Les tableaux en Java

5voto

Pshemo Points 34648

Vous avez raison. En dehors de cela, si nous voulons créer un tableau d'une taille spécifique rempli d'éléments fournis par une "usine", depuis Java 8 (qui introduit l'option API de flux ), nous pouvons utiliser cette phrase unique :

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A()) est comme une usine pour des éléments A séparés créés d'une manière décrite par lambda, () -> new A() qui est une mise en œuvre de Supplier<A> - il décrit comment chaque nouvelle instance A doit être créée.
  • limit(4) définit la quantité d'éléments que le flux va générer
  • toArray(A[]::new) (peut également être réécrit comme toArray(size -> new A[size]) ) - il nous permet de décider/décrire le type de tableau qui doit être retourné.

Pour certains types primitifs, vous pouvez utiliser DoubleStream , IntStream , LongStream qui fournissent en outre des générateurs comme range rangeClosed et quelques autres.

5voto

user1923551 Points 502

Voici un exemple clair de création d'un tableau de 10 objets employés, avec un constructeur qui prend un paramètre :

public class MainClass
{  
    public static void main(String args[])
    {
        System.out.println("Hello, World!");
        //step1 : first create array of 10 elements that holds object addresses.
        Emp[] employees = new Emp[10];
        //step2 : now create objects in a loop.
        for(int i=0; i<employees.length; i++){
            employees[i] = new Emp(i+1);//this will call constructor.
        }
    }
}

class Emp{
    int eno;
    public Emp(int no){
        eno = no;
        System.out.println("emp constructor called..eno is.."+eno);
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X