C有指针,Java有所谓的引用。从某种意义上说,它们有共同点,即它们都指向某个事物。我知道C中的指针存储它们指向的地址。参考也存储地址吗?除了指针更灵活,更容易出错之外,它们又有何不同?
final
Java中的引用几乎等同于C ++引用。它们不完全相等的原因是,C ++引用另外不可为空,而final
Java中的引用则可为空。
C有指针,Java有所谓的引用。从某种意义上说,它们有共同点,即它们都指向某个事物。我知道C中的指针存储它们指向的地址。参考也存储地址吗?除了指针更灵活,更容易出错之外,它们又有何不同?
final
Java中的引用几乎等同于C ++引用。它们不完全相等的原因是,C ++引用另外不可为空,而final
Java中的引用则可为空。
Answers:
引用可以通过存储地址来实现。 通常, Java引用将被实现为指针,但这不是规范所必需的。他们可能正在使用附加的间接层,以使垃圾收集更加容易。但是最后,它将(几乎总是)归结为涉及(Java风格)引用实现的(C风格)指针。
您不能使用引用进行指针运算。C语言中的指针与Java语言中的引用之间最重要的区别是,您实际上无法获取(和操纵)Java语言中的引用的基础值。换句话说:您不能执行指针运算。
在C语言中,您可以向指针(即地址)添加某些内容,也可以减去某些内容以指向“附近”的内容或指向任意位置的内容。
在Java中,引用仅指向一件事。您可以使变量持有不同的引用,但您不能仅仅要求它指向“原始事物之后的事物”。
引用是强类型的。另一个区别是,与C中的指针类型相比,Java 中对引用类型的控制要严格得多。在C中,您可以具有an int*
并将其强制转换为a,char*
然后重新解释该位置的内存。这种重新解释在Java中不起作用:您只能将引用另一端的对象解释为已经存在的某种东西(即Object
,仅当指向的对象实际上是a时,才能将引用转换为String
引用)。String
这些差异使C指针更强大,但也更加危险。这两种可能性(指针算术和重新解释所指向的值)都为C增加了灵活性,并且是该语言某些功能的源泉。但是它们也是问题的主要根源,因为如果使用不当,它们很容易破坏您的代码构建的假设。而且很容易错误地使用它们。
memcpy
将一个移动到char[]
),反之亦然。如果将指针转换为存储在某个位置的数字序列(可能在屏幕上显示并由操作员在纸条上向下复制),则计算机内的指针的所有副本都会被破坏,并且该数字序列将被转换回到一个指针(也许在操作员输入之后),该指针仍必须指向它之前所做的相同的事情。一个程序...
Java参考和C指针在两点上完全不同:
char
,int
等等)。有人写道,引用是强类型的,因为您不能强制编译器将an int*
视为a char*
。
完全排除特定转换实际上是安全的事实,C语言中没有多态性,因此比较是不容易的。
当然,Java比C具有更强的类型,并不是那是C指针与Java引用的功能,您需要使用JNI来打破类型安全性(除了忽略通用限制),但是即使在C中,您也必须强制编译器。
有人写道,Java引用可以实现为C指针,我敢肯定,由于JVM是用C实现的,因此它们在功能上通常不那么强大,因为它们在功能上通常不那么强大。尽管在64位计算机上,它们通常是压缩的普通对象指针(“压缩的OOP”),以节省空间和带宽。
无论如何,这些C指针也不必等同于硬件地址,即使它们通常(> 99%的实现)是出于性能原因。
最后,这是未向程序员公开的实现细节。
它们略有不同。在Java中,引用的副本被复制到被调用函数的堆栈中,指向与调用函数相同的对象,并允许您操纵该对象。但是,您不能更改调用函数所引用的对象。
考虑下面的java代码
public static void changeRValue(StringBuffer sb){
sb = new StringBuffer("helllllo"); /*attempt to assign the reference
to a new object*/
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("hi"); //Create a new string buffer
changeRValue(sb); //Call changeRValue
System.out.println(sb.toString()); //Prints "hi" not "hello"
}
现在考虑一下c ++中的指针:
void func(Dog* dog){
*dog = Dog("hello world"); //Change the value of dog to a new object
}
int main(int argc, const char * argv[]) {
Dog dog1("hi"); //Create a dog object
func(&dog1); //pass the address of dog
cout << dog1.name; //Prints "hello world" not hi.
return 0;
}