一个对象的生命周期由实例化阶段、使用阶段、释放阶段构成。
实例化阶段
有四种方式可以实现对象的实例化:第一种方式是使用new运算符进行对象的实例化;第二种方式是使用反射技术的newInstance()方法实例化对象;第三种方式是通过ObjectInputStream类的readObject()方法反序列化;第四种方式是通过对象的clone()方法进行现有对象的克隆。
案例1:建立Person类,定义name和age两个成员变量,定义showPerson()方法,输出name和age的值。建立PersonTest测试类,分别使用new运算符、反射技术的newInstance()方法、对象的clone()方法实例化对象。
新建项目PCoreUnit10,在PCoreUnit10项目新建memory包,在memory包下新建Person类。代码如下:
package memory;
/**
* @ClassName: Person
* @Description: 内存管理(对象的实例化)案例1
* @author 编程训练营
* @date
*
*/
public class Person implements Cloneable {
// name
String name;
// age
int age;
public Person(String name,int age)
{
this.name = name;
this.age = age;
}
/**
* @Title: showPerson
* @Description: 输出Person信息
* @param 参数
* @return void 返回类型
* @throws
*/
public void showPerson()
{
System.out.println("姓名:" + this.name);
System.out.println("年龄:" + this.age);
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* <p>Title: clone</p>
* <p>Description: </p>
* @return
* @throws CloneNotSupportedException
* @see java.lang.Object#clone()
*/
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Object obj = super.clone();
Person person = (Person)obj;
person.setName(this.name);
person.setAge(this.age);
return obj;
}
}Person类需要实现Cloneable接口的clone()方法,进行对象内容的复制。
在memory包下新建PersonTest类。代码如下:
package memory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import memory.Person;
/**
* @ClassName: PersonTest
* @Description: 内存管理(对象的实例化)案例1
* @author 编程训练营
* @date
*
*/
public class PersonTest {
/**
* @Title: main
* @Description:Java程序入口main方法
* @param @param args 参数
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
// 使用new运算符实例化Person对象
Person persona = new Person("张三",21);
persona.showPerson();
System.out.printf("persona对象的哈希码:%s\n",persona.hashCode());
// 使用反射技术的newInstance()方法实例化Person对象
Class<?> personClass = (Class) Person.class;
try {
Constructor paramConstructor = personClass.getConstructor(String.class, int.class);
Person personb = (Person) paramConstructor.newInstance("李四", 36);
if( null != personb )
{
personb.showPerson();
System.out.printf("personb对象的哈希码:%s\n",personb.hashCode());
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 使用对象的clone()方法复制对象
try {
Person personc = (Person)persona.clone();
personc.showPerson();
System.out.printf("personc对象的哈希码:%s\n",personc.hashCode());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}PersonTest程序分别使用new运算符、反射技术的newInstance()方法、对象的clone()方法实例化对象。
程序执行结果如下图所示:

当程序使用上面的方法实例化对象时,虚拟机会在堆中为对象分配内存,所有在对象的类中和父类中声明的变量都要分配内存,对象内存分配完成后,虚拟机会将实例变量初始化为默认的初始值,随后为实例变量赋正确的初始值。
使用阶段
对象被实例化后,虚拟机会把对象在堆中的内存首地址返回给内存申请者。此时对象被类变量或方法内的局部变量引用,对象进入使用阶段。虚拟机的垃圾收集器不会回收被有效变量引用的对象,这里的有效变量是指变量在有效范围内。例如在方法的执行过程总,方法的局部变量是有效的,方法执行完成后,方法内的局部变量就是无效的了。
释放阶段
当一个实例对象不再为程序所用时,也就是说当对象不再被有效的变量引用时,此时对象进入释放阶段。虚拟机必须释放这些实例对象占有的存储空间,此时实例对象被终结。当一个实例对象不再使用时,虚拟机并不是立即释放这些实例对象,而是要等待垃圾收集器再次进入回收周期后来释放这些实例对象,回收堆中的存储空间。