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

Раздел Оператор объединения строк + из Спецификации языка Java дает Вам еще некоторую справочную информацию о том, почему + оператор может быть настолько медленным.

101
задан Peter Lawrey 11 April 2016 в 10:44
поделиться

10 ответов

Все объекты в 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, новое ...) в такой же мере потенциальная ошибка и может привести к потере объекта, на который он указывает.

Система 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's 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's pointee

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

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

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

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's 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's pointee

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

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

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

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's 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's pointee

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

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

237
ответ дан 24 November 2019 в 04:36
поделиться

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

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

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

0
ответ дан 24 November 2019 в 04:36
поделиться

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

1
ответ дан 24 November 2019 в 04:36
поделиться

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

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

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

1
ответ дан 24 November 2019 в 04:36
поделиться

В Java нет указателей, как в C, но она позволяет создавать новые объекты в куче, на которые «ссылаются» переменные. Отсутствие указателей препятствует тому, чтобы программы Java незаконно ссылались на ячейки памяти, а также позволяет виртуальной машине Java автоматически выполнять сборку мусора.

10
ответ дан 24 November 2019 в 04:36
поделиться

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

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

31
ответ дан 24 November 2019 в 04:36
поделиться

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

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

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

43
ответ дан 24 November 2019 в 04:36
поделиться

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

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

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

3
ответ дан 24 November 2019 в 04:36
поделиться

Вы можете использовать адреса и указатели, используя класс Unsafe. Однако, как следует из названия, эти методы НЕ БЕЗОПАСНЫ и вообще плохая идея. Неправильное использование может привести к случайной смерти вашей JVM (на самом деле та же проблема связана с неправильным использованием указателей в C / C ++)

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

7
ответ дан 24 November 2019 в 04:36
поделиться

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

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

// (* говорит вам, что это указатель) Public Void MyMethod (Int * IntValue);

0
ответ дан 24 November 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: