如何使用Java中的指针?

How can I use pointers in Java?

我知道Java没有指针,但是我听说Java程序可以用指针创建,而这可以由Java中的少数人来完成。是真的吗?


Java中的所有对象都是引用,可以像指针一样使用它们。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;

取消对空值的引用:

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

混叠问题:

1
2
third = new Tiger();
first = third;

失去细胞:

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

您可以通过首先确保不再需要旧的second值或为另一个指针分配second值来确保安全。

1
2
first = second;
second = third; //OK

请注意,以其他方式给第二个值(空、新…)同样是一个潜在的错误,可能会导致丢失它指向的对象。

当您调用新的并且分配器不能分配请求的单元格时,Java系统将抛出一个异常(EDCOX1×1)。这是非常罕见的,并且通常是由溢出递归造成的。

请注意,从语言的角度来看,将对象丢弃到垃圾收集器根本不是错误。这只是程序员需要注意的事情。同一个变量可以在不同的时间指向不同的对象,当没有指针引用它们时,旧值将被回收。但是,如果程序的逻辑需要维护对对象的至少一个引用,它将导致错误。

新手经常犯以下错误。

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

你可能想说的是:

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

铸造不当:

1
2
3
4
5
6
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中的指针:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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中的指针:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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中没有这个。


Java确实有指针。任何时候在爪哇中创建一个对象,实际上是在创建一个指向该对象的指针;然后这个指针可以被设置为一个不同的对象或EDCOX1(0),并且原来的对象仍然存在(等待垃圾收集)。

在Java中不能做的是指针运算。不能取消对特定内存地址的引用或增加指针。

如果你真的想得到低级,唯一的方法是使用Java本机接口;即使如此,低级部分必须在C或C++中完成。


由于Java没有指针数据类型,所以在Java中使用指针是不可能的。即使是少数专家也无法使用Java中的指针。

参见最后一点:Java语言环境


Java不具有像C一样的指针,但它确实允许您在堆上创建新的对象,这些变量是由变量引用的。指针的缺乏是为了阻止Java程序非法引用内存位置,也使得Java虚拟机自动执行垃圾收集。


Java中有指针,但是在C++中,当你传递一个对象时,你不能用C++来操纵它们,你传递的是一个指向那个对象的指针,而不是和C++一样的意义。不能取消对该对象的引用。如果使用它的本地访问器设置它的值,它将改变,因为Java通过指针知道它的内存位置。但是指针是不可变的。当您试图设置指向新位置的指针时,您会得到一个与另一个同名的新本地对象。原始对象不变。这里有一个简短的程序来演示这个区别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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上运行。


可以使用不安全类使用地址和指针。然而,顾名思义,这些方法是不安全的,通常是一个坏主意。错误的使用可能导致JVM随机死亡(实际上,同样的问题在C/C++中使用指针不正确)。

虽然你可能习惯于使用指针并认为你需要它们(因为你不知道如何用其他方式编码),但你会发现你不需要,而且你会因此而变得更好。


Java中的所有对象都由引用拷贝传递给函数,但基元除外。

实际上,这意味着您将向原始对象发送指针的副本,而不是对象本身的副本。

如果你想要一个例子来理解这一点,请留下评论。


Java引用类型与C指针不一样,因为Java中没有指针的指针。


摘自戈弗雷诺兰的《反编译安卓》

安全性指示指针不是在Java中使用,这样黑客就不会脱离应用程序而进入操作系统。系统。没有指针意味着其他东西——在本例中是JVM——必须注意分配和释放内存。内存泄漏也应该成为过去的一件事,理论上是这样的。写入的一些应用程序因为程序员,C和C++因内存溢出而臭名昭著。不要注意在适当的时间释放不需要的记忆----不要任何读到这篇文章的人都会犯这样的罪。垃圾收集也应该使程序员更有效率,减少花在调试内存问题。


不,不是。

Java没有指针。如果你真的想要,你可以尝试通过围绕反射之类的东西来模仿它们,但是它拥有指针的所有复杂性,没有任何好处。

Java没有指针,因为它不需要指针。你希望从这个问题中得到什么样的答案,也就是说,在内心深处,你希望你能用它们做些什么,还是仅仅是好奇?


从技术上讲,所有Java对象都是指针。但是,所有基本类型都是值。无法手动控制这些指针。Java只是内部使用传递引用。


你也可以有文字指针。你必须自己实现它们。这对专家来说是非常基本的。使用一个int/object/long/byte数组,voila是实现指针的基础。现在,任何int值都可以是指向该数组int[]的指针。你可以增加指针,你可以减少指针,你可以乘以指针。你真的有指针算法!这是实现1000个int属性类并具有应用于所有属性的通用方法的唯一方法。也可以使用byte[]数组而不是int[]

不过,我希望Java可以让您通过引用传递文字值。沿着线的东西

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


正如其他人所说,简短的回答是"不"。

当然,您可以编写JAVA指针的JNI代码。这取决于你想完成什么,也许这会让你有所成就,也许不会。

您可以通过创建数组并使用数组中的索引来模拟指针。同样,这取决于你想完成什么,可能有用,也可能不有用。


所有Java对象都是指针,因为包含地址的变量称为指针和对象保持地址。因此对象是指针变量。