java中的引用与c中的指针

指针

首先要弄清楚指针和c中的指针是不一样的,前者是概念,后者是具体实例。

换句话说,C中的指针只是指针中的一种,其他语言也有指针,比如C++。但是我们同别人交流的时候,大都不会从概念上去交流,一般会选择其中一个实例去说,这个实例大部分时候都是C中的指针。久而久之,概念和实例被模糊化,C中的指针也成为了指针本身。

在这里我还是有必要给自己的大脑提个醒,不要将概念和实例混为一谈,要分清两者的界限。

指针定义

既然这么多语言都有自己的指针,那么这个指针到底是什么有没有一个明确的定义。

java中的引用与c中的指针
java中的引用与c中的指针

这是维基百科上的解释。

一句话解释就是 指针就是一个值,而这个值是某块内存的地址,通过这个值,就可以找到这块内存

C语言中的指针

C语言的指针具有以下特点

  • C语言的指针可以指向内存的任何地方。
  • C语言的指针可以参与数值运算,加法、减法。
  • C语言的指针还可以指向指针,以及指向指向指针的指针(因为指针就是一个值,也要存在内存中,所以它也有一个内存地址)

以上特点反映了指针寻地址的特性。

另外,指针这个东西,只关心内存的地址,不关心内存存的是什么东西,如果该地址中的对象被搬走了,指针不会自动改变指向。

Java中的引用

在了解引用之前,首先让我们先了解一下,java的引用类型。

在JAVA中数据可以简单分为两种类型, 基本类型引用 型。 继续细分的话基本类型又可以分为四种整数型 byteshort、int、long 两种浮点型 float、double 一种字符类型 char 一种布尔型  boolean。 引用类型可以说有无数种,包括String、数组、object等等。

在java种只有引用类型才有引用

基本类型内存分配

在基本类型中,你定义变量 int i = 0; 那么它在内存里的分配是这样的:内存里分配了一块空间,这块空间的名字是i,里面的内容是0

java中的引用与c中的指针
java中的引用与c中的指针

当你使用i的时候就可以访问这块空间里的内容。

引用类型内存分配

与基本类型内存分配不同, 引用类型在内存分配时,会分配两块内存,一块存储引用,一块存储值

比如在定义String s; 或者String s = null; 时。系统会分配一块内存用来引用值(在本例中装的是空值null,也就是什么也没有装)

java中的引用与c中的指针
java中的引用与c中的指针

至于具体这个s(引用)分配在哪,要看他被声明的位置。如果s被声明为局部变量,那s(引用)就在栈空间。如果不是局部变量,那就不在栈上分配。

当你为s赋值的时候,s = new String("wqlm");

情况发生了改变,引用有了一个明确的指向位置,引用的值也不再是空值。

java中的引用与c中的指针
java中的引用与c中的指针

从上例可以看到 在定义变量时 引用 没有 体,不占空 间, 只有在变量赋值时,引用才有实际值

java引用的实质

从上面可以看出,java的引用和c的指针很相似

java的引用也是一个值,但是这个值 不是某块内存的地址,而是某个值所在内存的地址 。他关注的是值,当值搬家后,引用也会跟着改──内存碎片整理

其实引用就是一个封装过的指针,它屏蔽了指针的复杂性,在编译器的实现中,引用最后还是会被转成指针

java的引用与c的指针的区别

  • java的引用是 某个值所在内存的地址。
  • c的指针是 某块内存的地址。
  • c的指针的值可以认为是个int类型,长度一般是计算机字长。
  • java的引用,声明变量时(不赋值),不占空间。(原因见引用类型内存分配)
  • java的引用初始值为 null。c的指针是int,如不初始化指针,那它的值就不是固定的了。
  • java的引用不可以计算。c的指针是int,他可以计算,如++或--,所以经常用指针来代替数组下标。

番外·java的引用传递

java的方法在传递参数时,一般有两种情况

  1. 参数是基本类型,直接将基本类型的值传递过来
  2. 参数是引用类型,将参数的引用值copy一份传递过来

因此,也可以说 java 只有值传递,所谓的引用传递,传递的是引用的值