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可以让您通过引用传递文字值。沿着线的东西
public void myMethod(int* intValue);
正如其他人所说,简短的回答是"不"。
当然,您可以编写JAVA指针的JNI代码。这取决于你想完成什么,也许这会让你有所成就,也许不会。
您可以通过创建数组并使用数组中的索引来模拟指针。同样,这取决于你想完成什么,可能有用,也可能不有用。
所有Java对象都是指针,因为包含地址的变量称为指针和对象保持地址。因此对象是指针变量。