it-swarm.com.de

Wie kann ich in Java Zeiger verwenden?

Ich weiß, dass Java keine Zeiger hat, aber ich habe gehört, dass Java Programme mit Zeigern erstellt werden können und dass dies von den wenigen Experten durchgeführt werden kann in Java. Ist es wahr?

98
user213038

Alle Objekte in Java sind Referenzen und können wie Zeiger verwendet werden.

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;

Null auswerten:

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

Aliasing-Problem:

third = new Tiger();
first = third;

Zellen verlieren:

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

Sie können dies sicherstellen, indem Sie zunächst sicherstellen, dass der alte Wert von second nicht mehr benötigt wird, oder indem Sie einem anderen Zeiger den Wert second zuweisen.

first = second;
second = third; //OK

Beachten Sie, dass das Vergeben eines zweiten Werts auf andere Weise (NULL, neu ...) ebenso ein potenzieller Fehler ist und zum Verlust des Objekts führen kann, auf das er verweist.

Das Java) System löst eine Ausnahme (OutOfMemoryError) aus, wenn Sie new aufrufen und der Allokator die angeforderte Zelle nicht zuordnen kann.

Beachten Sie, dass aus sprachlicher Sicht das Abgeben von Objekten an den Garbage Collector überhaupt keine Fehler darstellt. Es ist nur etwas, das dem Programmierer bewusst sein muss. Dieselbe Variable kann zu verschiedenen Zeiten auf verschiedene Objekte verweisen, und alte Werte werden wiederhergestellt, wenn kein Zeiger auf sie verweist. Wenn für die Logik des Programms jedoch mindestens ein Verweis auf das Objekt erforderlich ist, wird ein Fehler verursacht.

Anfänger machen oft den folgenden Fehler.

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

Was Sie wahrscheinlich sagen wollten, war:

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

Unsachgemäßes Casting:

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.

Zeiger in 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
}

Zeiger in 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
    }
} 

PDATE: wie in den Kommentaren vorgeschlagen, muss man beachten, dass C Zeigerarithmetik hat. In Java haben wir das jedoch nicht.

233
Sajad Bahmani

Java hat Zeiger. Jedes Mal, wenn Sie ein Objekt in Java erstellen, erstellen Sie tatsächlich einen Zeiger auf das Objekt. Dieser Zeiger könnte dann auf ein anderes Objekt oder auf null gesetzt werden, und das ursprüngliche Objekt bleibt bestehen (ausstehende Speicherbereinigung).

Was Sie mit Java nicht tun können, ist Zeigerarithmetik. Sie können eine bestimmte Speicheradresse nicht dereferenzieren oder einen Zeiger inkrementieren.

Wenn Sie wirklich ein niedriges Level erreichen möchten, können Sie dies nur mit der Java Native Interface ; und selbst dann muss der Teil auf niedriger Ebene in C oder C++ ausgeführt werden.

42
Michael Myers

Da Java keine Zeigerdatentypen hat, können in Java keine Zeiger verwendet werden. Selbst die wenigen Experten können in Java keine Zeiger verwenden.

Siehe auch den letzten Punkt in: Die Java Sprachumgebung

30
Fortega

Java hat keine Zeiger wie C, aber es erlaubt Ihnen, neue Objekte auf dem Heap zu erstellen, die von Variablen "referenziert" werden. Der Mangel an Zeigern besteht darin, zu verhindern, dass Java Programme illegal auf Speicherstellen verweisen, und die Garbage Collection kann auch automatisch von der Java= Virtual Machine ausgeführt werden.

9
Zubair

Mit der Klasse Unsafe können Sie Adressen und Zeiger verwenden. Wie der Name schon sagt, sind diese Methoden UNSICHER und im Allgemeinen eine schlechte Idee. Falsche Verwendung kann dazu führen, dass Ihre JVM nach dem Zufallsprinzip abstirbt (tatsächlich wird das gleiche Problem durch die falsche Verwendung von Zeigern in C/C++ verursacht).

Während Sie vielleicht an Zeiger gewöhnt sind und glauben, dass Sie sie brauchen (weil Sie nicht wissen, wie Sie auf andere Weise codieren können), werden Sie feststellen, dass Sie dies nicht tun, und Sie sind besser dran.

7
Peter Lawrey

In Java gibt es Zeiger, die Sie jedoch nicht wie in C++ oder C bearbeiten können. Wenn Sie ein Objekt übergeben, übergeben Sie einen Zeiger auf dieses Objekt, jedoch nicht im gleichen Sinne wie in C++. Dieses Objekt kann nicht dereferenziert werden. Wenn Sie die Werte mit den systemeigenen Zugriffsmethoden festlegen, ändert sich dies, weil Java den Speicherort über den Zeiger kennt. Der Zeiger ist jedoch unveränderlich. Wenn Sie versuchen, den Zeiger auf einen neuen Speicherort zu setzen, Stattdessen erhalten Sie ein neues lokales Objekt mit demselben Namen wie das andere. Das ursprüngliche Objekt bleibt unverändert. Hier ist ein kurzes Programm, um den Unterschied zu demonstrieren.

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;
    }
}

Dies kann bei Ideone.com ausgeführt werden.

7
kingfrito_5005

Alle Objekte in Java) werden per Referenzkopie an Funktionen übergeben, mit Ausnahme von Primitiven.

Tatsächlich bedeutet dies, dass Sie eine Kopie des Zeigers an das ursprüngliche Objekt und nicht an eine Kopie des Objekts selbst senden.

Bitte hinterlassen Sie einen Kommentar, wenn Sie dies anhand eines Beispiels verstehen möchten.

3
coolest_head

Java-Referenztypen sind nicht mit C-Zeigern identisch, da Sie in Java keinen Zeiger auf einen Zeiger haben können.

2
zezba9000

Technisch gesehen sind alle Java - Objekte Zeiger. Alle primitiven Typen sind jedoch Werte. Es gibt keine Möglichkeit, diese Zeiger manuell zu steuern. Java verwendet nur intern pass -durch-Referenz.

1
Poindexter

Nicht wirklich, nein.

Java hat keine Zeiger. Wenn Sie wirklich wollten, könnten Sie versuchen, sie zu emulieren, indem Sie etwas wie Reflektion aufbauen, aber es hätte die gesamte Komplexität von Zeigern mit keinem der Vorteile.

Java hat keine Zeiger, weil es sie nicht benötigt. Auf welche Art von Antworten haben Sie bei dieser Frage gehofft, d. H. Tief im Inneren haben Sie gehofft, Sie könnten sie für etwas verwenden, oder war das nur Neugierde?

1
Andrzej Doyle

aus dem Buch namens Decompiling Android von Godfrey Nolan

Die Sicherheit schreibt vor, dass Zeiger werden in Java nicht verwendet damit Hacker nicht aus einer Anwendung in das Betriebssystem eindringen können. Keine Zeiger bedeuten, dass sich etwas anderes - in diesem Fall die JVM - um die Zuweisung und Freigabe des Speichers kümmern muss. Speicherlecks sollten ebenfalls der Vergangenheit angehören, so die Theorie. Einige in C und C++ geschriebene Anwendungen sind dafür berüchtigt, Speicher wie ein Sieb zu verlieren, da Programmierer nicht darauf achten, unerwünschten Speicher zum richtigen Zeitpunkt freizugeben - nicht, dass jemand, der dies liest, einer solchen Sünde schuldig wäre. Die Garbage Collection sollte außerdem die Produktivität von Programmierern steigern und weniger Zeit für das Debuggen von Speicherproblemen aufwenden.

1
Mustafa Güven

Wie andere gesagt haben, lautet die kurze Antwort "Nein".

Sicher, Sie könnten JNI-Code schreiben, der mit Java) - Zeigern abgespielt wird. Je nachdem, was Sie erreichen möchten, würde das Sie vielleicht irgendwohin bringen, und vielleicht würde es nicht.

Sie können Punkte jederzeit simulieren, indem Sie ein Array erstellen und mit Indizes im Array arbeiten. Je nachdem, was Sie erreichen möchten, kann dies wiederum nützlich sein oder auch nicht.

0
Jay

sie können auch Hinweise für Literale haben. Sie müssen sie selbst implementieren. Es ist ziemlich einfach für Experten;). Verwenden Sie ein Array aus int/object/long/byte und voila, um Zeiger zu implementieren. Jetzt kann jeder int-Wert ein Zeiger auf das Array int [] sein. Sie können den Zeiger inkrementieren, Sie können den Zeiger dekrementieren, Sie können den Zeiger multiplizieren. Sie haben in der Tat Zeigerarithmetik! Nur so können 1000 int -Attributklassen implementiert werden und es steht eine generische Methode zur Verfügung, die für alle Attribute gilt. Sie können auch ein Byte-Array [] anstelle eines Int-Arrays [] verwenden.

Ich möchte jedoch, dass Sie mit Java) literale Werte als Referenz übergeben können. Etwas in die richtige Richtung

//(* telling you it is a pointer) public void myMethod(int* intValue);

0
Mordan