Подтвердить что ты не робот

Как я могу использовать указатели в Java?

Я знаю, что Java не имеет указателей, но я слышал, что Java-программы могут быть созданы с помощью указателей и что это могут сделать те немногие, кто является экспертом в java. Это правда?

4b9b3361

Ответ 1

Все объекты в Java являются ссылками, и вы можете использовать их как указатели.

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;

Вызов нулевого значения:

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

Проблема с псевдонимами:

third = new Tiger();
first = third;

Потеря клеток:

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

Вы можете сделать это безопасным, сначала убедившись, что больше нет необходимости в старом значении секунды или присваивании другому указателю значения второго.

first = second;
second = third; //OK

Обратите внимание, что предоставление второго значения другими способами (NULL, new...) является такой же потенциальной ошибкой и может привести к потере объекта, на который он указывает.

Система Java генерирует исключение (OutOfMemoryError) при вызове new, и распределитель не может выделить запрошенную ячейку. Это очень редко и обычно является результатом рекурсии бега.

Обратите внимание, что с точки зрения языка отказ от объектов в сборщике мусора вообще не является ошибкой. Это то, о чем программист должен знать. Одна и та же переменная может указывать на разные объекты в разное время, и старые значения будут исправлены, если указатель не ссылается на них. Но если логика программы требует поддержания хотя бы одной ссылки на объект, она вызовет ошибку.

Новички часто делают следующую ошибку.

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

Что вы, вероятно, хотели сказать:

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

Неправильное литье:

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.

Указатели в 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 pointee

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

Указатели в 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 pointee

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

ОБНОВЛЕНИЕ:, как это предлагается в комментариях, нужно отметить, что C имеет арифметику указателя. Однако у нас этого нет в Java.

Ответ 2

В Java есть указатели. Каждый раз, когда вы создаете объект в Java, вы на самом деле создаете указатель на объект; этот указатель затем может быть установлен на другой объект или на null, и исходный объект все равно будет существовать (ожидающая сборка мусора).

То, что вы не можете сделать в Java, - это арифметика указателей. Вы не можете разыменовывать определенный адрес памяти или увеличивать указатель.

Если вы действительно хотите получить низкий уровень, единственный способ сделать это - Java Native Interface; и даже тогда часть низкого уровня должна быть выполнена на C или С++.

Ответ 3

Поскольку у Java нет типов данных указателя, невозможно использовать указатели в Java. Даже немногие эксперты не смогут использовать указатели в java.

См. также последний пункт в: Языковая среда Java

Ответ 4

В Java нет указателей, таких как C, но это позволяет создавать новые объекты в куче, которые "ссылаются" на переменные. Отсутствие указателей заключается в том, чтобы запретить Java-программам незаконное обращение к ячейкам памяти, а также позволяет автоматически собирать Garbage Collection виртуальной машиной Java.

Ответ 5

Вы можете использовать адреса и указатели, используя класс Unsafe. Однако, как следует из названия, эти методы являются UNSAFE и, как правило, плохая идея. Неправильное использование может привести к случайному угасанию вашего JVM (на самом деле одна и та же проблема неправильно использует указатели на C/С++)

Пока вы можете использовать указатели и считаете, что вам нужны они (потому что вы не знаете, как закодировать каким-либо другим способом), вы обнаружите, что вы этого не сделаете, и вам будет лучше для него.

Ответ 6

В Java есть указатели, но вы не можете манипулировать ими так, как вы можете на С++ или C. Когда вы передаете объект, вы передаете указатель на этот объект, но не в том же смысле, что и на С++. Этот объект не может быть разыменован. Если вы установите его значения с помощью своих собственных аксессуаров, это изменится, потому что Java знает свою ячейку памяти через указатель. Но указатель неизменен. Когда вы пытаетесь установить указатель на новое место, вместо этого вы получите новый локальный объект с тем же именем, что и другой. Исходный объект не изменяется. Вот краткая программа, демонстрирующая разницу.

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

Это можно запустить на Ideone.com.

Ответ 7

Все объекты в java передаются в функции с помощью ссылочной копии, кроме примитивов.

По сути, это означает, что вы отправляете копию указателя на исходный объект, а не на копию самого объекта.

Пожалуйста, оставьте комментарий, если вы хотите, чтобы этот пример понял.

Ответ 8

Не совсем, нет.

В Java нет указателей. Если вы действительно хотели, вы могли бы попытаться имитировать их, создав вокруг что-то вроде отражения, но у него будет все сложность указателей без каких-либо преимуществ .

У Java нет указателей, потому что они им не нужны. На какие ответы вы надеялись на этот вопрос, то есть в глубине души, вы надеялись, что сможете использовать их для чего-то или это просто любопытство?

Ответ 9

из книги "Декомпиляция Android от Godfrey Nolan"

Безопасность определяет, что указатели arent используется в Java, поэтому хакеры могут не выходить из приложения и работать система. Никакие указатели не означают, что что-то другое - в этом случае JVM ---- должен позаботьтесь о распределении и освобождении памяти. Утечка памяти также должна ушли в прошлое, или так теория идет. Некоторые приложения, написанные на C и С++ известны тем, что они пропускают память, как сито, потому что программисты не обращайте внимания на освобождение нежелательной памяти в соответствующее время - нет что любой, кто читает это, будет виноват в таком грехе. Вывоз мусора также должны сделать программистов более продуктивными, с меньшим затраченным временем проблемы с отладочной памятью.

Ответ 10

Типы ссылок Java не совпадают с указателями C, поскольку у вас не может быть указатель на указатель на Java.

Ответ 11

Технически, все объекты Java являются указателями. Однако все примитивные типы являются значениями. Невозможно вручную управлять этими указателями. Java только внутренне использует pass-by-reference.

Ответ 12

Как говорили другие, короткий ответ - "Нет".

Конечно, вы можете написать код JNI, который воспроизводится с помощью указателей Java. В зависимости от того, что вы пытаетесь выполнить, возможно, это приведет вас куда-то, и, возможно, это не так.

Вы всегда можете моделировать точки, создавая массив и работая с индексами в массиве. Опять же, в зависимости от того, что вы пытаетесь выполнить, это может быть или не быть полезным.

Ответ 13

у вас также могут быть указатели на литералы. Вы должны реализовать их самостоятельно. Это довольно просто для экспертов;). Используйте массив из int/object/long/byte и voila, у вас есть основы для реализации указателей. Теперь любое значение int может быть указателем на этот массив int []. Вы можете увеличить указатель, вы можете уменьшить указатель, вы можете умножить указатель. У вас действительно есть указательная арифметика! Это единственный способ реализовать 1000 классов атрибутов int и иметь общий метод, который применяется ко всем атрибутам. Вы также можете использовать массив byte [] вместо int []

Однако я бы хотел, чтобы Java позволяла передавать литеральные значения по ссылке. Что-то вдоль линий

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

Ответ 14

Все объекты java являются указателями, потому что переменная, которая содержит адрес, называется указателем, а объект hold address.so - переменная-указатель.