概念
在Java中,我们听到最多的词,可能就是“对象”这个词了,同时也有着 “一切皆对象” 的说法。
对象很好理解,比如“人”是一个类,那么每一个真实存在的人就是一个对象,那么什么叫对象的引用呢?要搞清这个问题,我们需要先了解另外一个问题,那就是Java的内存分配策略,下面是一个简略的分配图:
从上图我们可以很清晰明白的看到,Java在运行时内存的分配是分为三个区的,
1:静态存储区,只要用来存储static数据和常量,这块内存在程序编译的时候就已经分配好了,并且在整个程序运行期间都是存在的。
2:栈区,当方法被执行时,方法体内的局部变量(基本数据类型,对象的引用)都在栈上创建,并在方法执行结束时会被清空(这里涉及到Java的垃圾回收机制,不详述)。因为栈内存分配运行内置于处理器的指令集中,效率很高,但是分配的内存容量相当有限。
3:堆区,又成为动态内存分配区,所有一切new出来的对象都是存放在该区内。这部分内存在不使用时将会由Java的垃圾回收器(GC)回收,下面具体讲。
了解了上面的内容,那么我们接下来就好讲了。首先我们来看一段代码
package com.example;
/**
* @author LuoSiye
* Created on 2016-10-13 .
*/
public class Person {
String name;
boolean sex;
int age;
public Person(String name, boolean sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
很简单,一个Person类,再来看测试类:
package com.example;
/**
* @author LuoSiye
* Created on 2016-10-10 .
*/
public class MainTest {
public static void main(String[] args) {
Person person = new Person("Lucy",true,25);
}
}
在main方法中我们看到,外部可以调用类来创建对象,创建了一个Person对象person,我们来深入的研究一下:
1:首先看 “=”的右边,new 了一个Person,那么根据上面的知识我们知道,这个对象是存在于堆区当中的,它保存了这个对象的数据和方法。
2:“=”的左边,根据我们上面说的,方法内部只创建基本数据类型和对象的引用,说白了,它和C/C++中的指针是相似的,就是一个内存地址,所以,person其实就是一个指向右边new出来的对象的地址,这就被称作为该对象的引用。
垃圾回收
上面我们讲到了Java的垃圾回收,这里具体的讲一下:
随着方法调用的结束,基本数据类型和引用会被清空,而对象由于存在于堆区中,不会被清空。而堆区的对象什么时候回收呢?当没有任何的引用指向该对象时,则该对象会被回收,按这句话的意思来理解,一个对象可能会有多个引用,怎么理解这句话呢,我们来看一段代码:
package com.example;
/**
* @author LuoSiye
* Created on 2016-10-10 .
*/
public class MainTest {
public static void main(String[] args) {
Person person = new Person("Lucy",true,25);
Person person1 = person;//将person对象引用赋值给person1.
}
}
还是上面的代码,只是加了一行赋值,来看张图:
person和person1都指向该对象,那么,一个引用,可不可以有多个对象呢?显然是可以的,比如说我们这样写一段代码:
package com.example;
/**
* @author LuoSiye
* Created on 2016-10-10 .
*/
public class MainTest {
public static void main(String[] args) {
boolean flag = true;
Person person = new Person("Lucy",true,25);//第一次指向Lucy这个人.
if(flag){
person = new Person("jack",false,26);//第二次指向jack这个人.
}
}
}
从代码和注释可以看到,person一个引用,指向了两个对象。
参数传递
知道了上面的知识,我们就知道了,方法在传递参数时的情况了:
1:当参数是基本数据类型时,那么我们传递的是值本身的复制,它是不会影响到变量本身的;
2:当参数是非基本数据类型是,那么传递的就是对象引用的复制,引用的值传递,意味着对象的地址被复制,并传递给Java方法。Java方法根据该引用的访问将会影响对象;
OK,引用就讲这些。