我知道Java没有指针,但是我听说可以用指针创建Java程序,而这可由少数Java专家来完成。是真的吗
我知道Java没有指针,但是我听说可以用指针创建Java程序,而这可由少数Java专家来完成。是真的吗
Answers:
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;
取消引用null:
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
请注意,以其他方式给second赋值(NULL,new ...)与潜在错误一样多,并且可能会导致丢失其指向的对象。
OutOfMemoryError
当您调用new并且分配器无法分配所请求的单元格时,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中没有。
Java确实有指针。每当使用Java创建对象时,实际上就是在创建指向该对象的指针。然后可以将此指针设置为其他对象或null
,并且原始对象仍将存在(等待垃圾回收)。
您在Java中无法做的是指针运算。您不能取消引用特定的内存地址或增加指针。
如果您真的想获得低级,唯一的方法是使用Java本机接口。即使这样,低级部分也必须使用C或C ++完成。
由于Java没有指针数据类型,因此无法在Java中使用指针。即使是少数专家也将无法在Java中使用指针。
另请参见:Java语言环境中的最后一点。
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所具有的指针,但是它允许您在堆上创建被变量“引用”的新对象。缺少指针是为了阻止Java程序非法引用内存位置,并且还使Java虚拟机可以自动执行垃圾回收。
您可以使用Unsafe类使用地址和指针。但是,顾名思义,这些方法是不安全的,通常是个坏主意。使用不正确会导致JVM随机死亡(实际上,在C / C ++中使用指针不正确会导致相同的问题)
尽管您可能习惯于使用指针并认为自己需要它们(因为您不知道如何以其他任何方式编码),但您会发现自己不使用指针,并且会因此而受益。
从技术上讲,所有Java对象都是指针。尽管所有原始类型都是值。无法对这些指针进行手动控制。Java仅在内部使用按引用传递。
不是,不是
Java没有指针。如果您真的想要,可以尝试通过围绕反射之类的东西来模拟它们,但是它将具有指针的所有复杂性,而没有任何好处。
Java没有指针,因为它不需要它们。您希望从这个问题中得到什么样的答案,即您内心深处希望自己可以将其用于某些事情,还是只是出于好奇?
除了原语外,java中的所有对象都通过引用副本传递给函数。
实际上,这意味着您要发送指向原始对象的指针的副本,而不是对象本身的副本。
如果您想举例说明,请发表评论。
swap
Java 编写将交换两个对象的函数。
摘自Godfrey Nolan的《反编译Android》一书
安全性要求Java中不使用指针,因此黑客无法脱离应用程序进入操作系统。没有指针意味着其他东西(在这种情况下为JVM)必须负责分配和释放内存。内存泄漏也应该成为过去,或者理论如此。一些用C和C ++编写的应用程序因泄漏像筛子一样而臭名昭著,因为程序员没有注意在适当的时候释放不需要的内存,而不是任何人读这本书都会犯这种罪。垃圾回收还应该提高程序员的生产率,减少调试内存问题的时间。
您也可以使用文字指针。您必须自己实现它们。对于专家来说,这是非常基本的;)。使用int / object / long / byte和voila数组,您具有实现指针的基础。现在,任何int值都可以是指向该数组int []的指针。您可以递增指针,可以递减指针,可以乘以指针。您确实有指针算术!这是实现1000个int属性类并具有适用于所有属性的通用方法的唯一方法。您也可以使用byte []数组代替int []
但是,我希望Java允许您通过引用传递文字值。沿线的东西
//(* telling you it is a pointer)
public void myMethod(int* intValue);