138 votes

Comment utiliser les pointeurs en Java ?

Je sais que Java n'a pas de pointeurs, mais j'ai entendu dire que les programmes Java peuvent être créés avec des pointeurs et que cela peut être fait par les quelques experts en Java. Est-ce vrai ?

270voto

SjB Points 6823

Tous les objets en Java sont des références et vous pouvez les utiliser comme des pointeurs.

abstract class Animal
{...
}

class Lion extends Animal
{...
}

class Tiger extends Animal
{   
public Tiger() {...}
public void growl(){...}
}

Tiger first = null;
Tiger second = new Tiger();
Tiger third;

Déréférencement d'un null :

first.growl();  // ERROR, first is null.    
third.growl(); // ERROR, third has not been initialized.

Problème d'aliasing :

third = new Tiger();
first = third;

Perdre des cellules :

second = third; // Possible ERROR. The old value of second is lost.    

Vous pouvez sécuriser cette opération en vous assurant d'abord qu'il n'y a plus besoin de l'ancienne valeur de seconde ou en assignant à un autre pointeur la valeur de seconde.

first = second;
second = third; //OK

Notez que donner à second une valeur d'une autre manière (NULL, new...) est tout autant une erreur potentielle et peut entraîner la perte de l'objet vers lequel il pointe.

Le système Java lèvera une exception ( OutOfMemoryError ) lorsque vous appelez new et que l'allocateur ne peut pas allouer la cellule demandée. Ceci est très rare et résulte généralement d'une récursion qui s'emballe.

Notez que, du point de vue du langage, l'abandon d'objets au ramasseur d'ordures n'est pas du tout une erreur. C'est juste quelque chose dont le programmeur doit être conscient. La même variable peut pointer vers différents objets à différents moments et les anciennes valeurs seront récupérées lorsqu'aucun pointeur ne les référencera. Mais si la logique du programme exige de maintenir au moins une référence à l'objet, cela provoquera une erreur.

Les novices commettent souvent l'erreur suivante.

Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed. 

Ce que tu voulais probablement dire, c'est :

Tiger tony = null;
tony = third; // OK.

Coulée incorrecte :

Lion leo = new Lion();
Tiger tony = (Tiger)leo; // Always illegal and caught by compiler. 

Animal whatever = new Lion(); // Legal.
Tiger tony = (Tiger)whatever; // Illegal, just as in previous example.
Lion leo = (Lion)whatever; // Legal, object whatever really is a Lion.

Les pointeurs en C :

void main() {   
    int*    x;  // Allocate the pointers x and y
    int*    y;  // (but not the pointees)

    x = malloc(sizeof(int));    // Allocate an int pointee,
                                // and set x to point to it

    *x = 42;    // Dereference x to store 42 in its pointee

    *y = 13;    // CRASH -- y does not have a pointee yet

    y = x;      // Pointer assignment sets y to point to x's pointee

    *y = 13;    // Dereference y to store 13 in its (shared) pointee
}

Les pointeurs en Java :

class IntObj {
    public int value;
}

public class Binky() {
    public static void main(String[] args) {
        IntObj  x;  // Allocate the pointers x and y
        IntObj  y;  // (but not the IntObj pointees)

        x = new IntObj();   // Allocate an IntObj pointee
                            // and set x to point to it

        x.value = 42;   // Dereference x to store 42 in its pointee

        y.value = 13;   // CRASH -- y does not have a pointee yet

        y = x;  // Pointer assignment sets y to point to x's pointee

        y.value = 13;   // Deference y to store 13 in its (shared) pointee
    }
} 

UPDATE : comme suggéré dans les commentaires, il faut noter que le C a une arithmétique de pointeur. En revanche, nous n'en disposons pas en Java.

54voto

Fortega Points 8890

Comme Java n'a pas de types de données de pointeur, il est impossible d'utiliser des pointeurs en Java. Même les quelques experts ne seront pas en mesure d'utiliser les pointeurs en Java.

Voir aussi le dernier point dans : L'environnement du langage Java

50voto

Michael Myers Points 82361

Java a des pointeurs. Chaque fois que vous créez un objet en Java, vous créez en fait un pointeur sur l'objet ; ce pointeur peut ensuite être défini sur un objet différent ou sur null et l'objet original existera toujours (en attendant le ramassage des ordures).

Ce que vous ne pouvez pas faire en Java, c'est l'arithmétique des pointeurs. Vous ne pouvez pas déréférencer une adresse mémoire spécifique ou incrémenter un pointeur.

Si vous voulez vraiment descendre au niveau le plus bas, la seule façon de le faire est d'utiliser la fonction Interface native Java et même dans ce cas, la partie de bas niveau doit être réalisée en C ou C++.

12voto

kingfrito_5005 Points 551

Il existe des pointeurs en Java, mais vous ne pouvez pas les manipuler comme vous le faites en C++ ou en C. Lorsque vous passez un objet, vous passez un pointeur sur cet objet, mais pas dans le même sens qu'en C++. Cet objet ne peut pas être déréférencé. Si vous définissez ses valeurs à l'aide de ses accesseurs natifs, il changera parce que Java connaît son emplacement mémoire par le biais du pointeur. Mais le pointeur est immuable. Lorsque vous tentez de définir le pointeur à un nouvel emplacement, vous vous retrouvez avec un nouvel objet local portant le même nom que l'autre. L'objet original reste inchangé. Voici un bref programme pour démontrer la différence.

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone {

    public static void main(String[] args) throws java.lang.Exception {
        System.out.println("Expected # = 0 1 2 2 1");
        Cat c = new Cat();
        c.setClaws(0);
        System.out.println("Initial value is " + c.getClaws());
        // prints 0 obviously
        clawsAreOne(c);
        System.out.println("Accessor changes value to " + c.getClaws());
        // prints 1 because the value 'referenced' by the 'pointer' is changed using an accessor.
        makeNewCat(c);
        System.out.println("Final value is " + c.getClaws());
        // prints 1 because the pointer is not changed to 'kitten'; that would be a reference pass.
    }

    public static void clawsAreOne(Cat kitty) {
        kitty.setClaws(1);
    }

    public static void makeNewCat(Cat kitty) {
        Cat kitten = new Cat();
        kitten.setClaws(2);
        kitty = kitten;
        System.out.println("Value in makeNewCat scope of kitten " + kitten.getClaws());
        //Prints 2. the value pointed to by 'kitten' is 2
        System.out.println("Value in makeNewcat scope of kitty " + kitty.getClaws());
        //Prints 2. The local copy is being used within the scope of this method.
    }
}

class Cat {

    private int claws;

    public void setClaws(int i) {
        claws = i;
    }

    public int getClaws() {
        return claws;
    }
}

Il peut être exécuté sur Ideone.com.

11voto

Zubair Points 11039

Java n'a pas de pointeurs comme le C, mais il vous permet de créer de nouveaux objets sur le tas qui sont "référencés" par des variables. L'absence de pointeurs a pour but d'empêcher les programmes Java de référencer illégalement des emplacements mémoire et permet également à la machine virtuelle Java d'effectuer automatiquement la collecte des déchets.

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