我知道Java没有指针,但我听说Java程序可以使用指针创建,并且只有少数精通Java的人才能做到。这是真的吗?
我知道Java没有指针,但我听说Java程序可以使用指针创建,并且只有少数精通Java的人才能做到。这是真的吗?
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.
您可以通过先确保不再需要 second 的旧值或将另一个指针赋值为 second 的值来使其更安全。
first = second;
second = third; //OK
请注意,以其他方式(NULL、new...)为second参数赋值同样可能导致错误,并可能导致指针指向的对象丢失。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中我们没有这个。
由于Java没有指针数据类型,因此在Java中无法使用指针。即使是少数专家也无法在Java中使用指针。
另请参见:Java语言环境中的最后一点。
Dog d = new Dog(); d.bark();
与C++中的Dog *d = new Dog(); d->bark();
是相同的。不同之处在于,在Java中,您无法获取对非对象的指针的引用,并且无法解除引用对象指针。您也无法将其转换为数字并进行数学运算。通过null
指针访问对象将获得NullPointerException
。 - Michael TsangJava确实有指针。在Java中,每当你创建一个对象时,实际上是在创建一个指向该对象的指针;这个指针可以被设置为不同的对象或null
,而原始对象仍将存在(等待垃圾回收)。
但在Java中不能进行指针算术运算。你无法解引用特定的内存地址或递增一个指针。
如果你真的想要获得低级别的操作,唯一的方法是使用Java Native Interface;即使这样,低级别的部分也必须用C或C++来完成。
Java 中存在指针,但是你不能像在 C++ 或 C 中那样操纵它们。当你传递一个对象时,你正在传递一个指向该对象的指针,但不是像在 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上运行。
Java不像C语言一样具有指针(Pointer)概念,但它允许你在堆(heap)上创建新的对象,并由变量引用。没有指针是为了防止Java程序非法引用内存地址,同时也使得Java虚拟机(JVM)能够自动进行垃圾回收(Garbage Collection)。
从技术上讲,所有的Java对象都是指针。但是所有的原始类型都是值。没有办法手动控制这些指针。Java内部只使用按引用传递。
swap
函数。 - Michael Tsang