对象在内存中的具体存储方式到底是什么样子的呢?这就要提出“对象引用”这个概念
public class Test
{
public static void main(String[] args)
{
Human aPerson = new Human(160);
}
}
class Human
{
/**
* constructor
*/
public Human(int h)
{
this.height = h;
}
/**
* accessor
*/
public int getHeight()
{
return this.height;
}
/**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
}
private int height;
}
一般创建类的对象的时候直接使用new给类开辟空间。
Human aPerson = new Human(160);
这个语句的具体操作是什么呢? ^_^
1. 首先看等号的右侧,new是在内存中为对象开辟空间,具体来说,new是在内存的堆(heap)上为对象开辟空间。这一空间中,保存有对象的数据和方法。
2. 等号左侧,aPerson指代一个human对象,这个被称为对象引用。实际上,aPerson并不是对象本身,而是类似于指向对象的指针。aPerson存在于内存的栈(Stack)中。
3. 当我们用等号赋值时,是将对象在内存中的地址赋给对象引用aPerson。
Java在编译运行时所说的内存指的是JVM(Java Virtual Machine)虚拟出来的Java线程内存空间。
每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧。Java栈和帧在内存中也不必是连续的,栈是以帧为单位保存当前线程的运行状态。
<1> 栈的读取速度比堆快,但栈上存储的数据受到有效范围的控制,C语言中一次函数调用结束,栈最底部的栈帧消除,里面存储的参量和变量自动消失。Java中栈也是这样。Java中所有的普通对象都存储在堆上,也就是说new的时候是在堆上面开辟一个类的对象的空间。
human h1 = new human(121);
human h2 = h1;
当你执行这个操作的时候内存中一共只有一个对象,两个指针都指向这个对象。使用h2对对象进行操作的时候h1这边也会看到。
<2> 基本类型的对象呢?比如说int,double,都保存在栈上。基本类型是不需要new的,声明的时候直接 int(double) var1;一旦声明,将直接在栈上直接存储基本类型的数据。所以基本类型的变量名也不叫作引用。
讲了很基础的对象和引用后,有一个问题Java中参数传递是值传递呢还是引用传递?
我的理解是: Java的参数传递为值传递。也就是说,当我们传递一个参数时,方法将获得该参数的一个拷贝。
Java中参数的传递应该就是两种情况:基本类型的参数和引用类型的参数。
1> 基本类型的值传递是说变量本身被复制并传递给Java方法,Java方法对该副本的修改不会影响原来的变量。
2> 引用的值传递指的是对象的地址被传过去,Java方法中的行参会指向堆里面的对象,在Java方法中对对象的修改是影响到原对象的。