上代码:
1 public class ReferenceTest { 2 public static void main(String[] args) { 3 //test1();//软引用 4 //test2();//弱引用 5 //test3();//幽灵引用_1 6 test4();//幽灵引用_2 7 8 } 9 public static void test1(){ 10 //在堆中创建一个对象Obj 11 //在栈中创建一个p来强引用此对象Obj 12 Person p=new Person(1); 13 14 //在栈中创建一个softReference来软引用此对象Obj 可以获取对象的属性值 15 SoftReference<Person> softReference=new SoftReference<Person>(p); 16 System.out.println(p.getId());//输出打印:1 17 System.out.println(softReference.get().getId());//输出打印:1 18 19 //断开p和Obj的强引用 20 p=null; 21 //System.out.println(p.getId()); 22 //System.gc(); 23 System.out.println(softReference.get().getId());//输出打印:1 24 //并不报空指针异常 虽然断开了p和Obj的强引用,但是并没有被回收. 25 //如果在前面调用gc() 垃圾回收 运行结果也是打印1的..软引用只有系统在发生内存溢出异常之前,会把只被软引用的对象进行回收 26 } 27 28 public static void test2(){ 29 //在堆中创建一个对象Obj 30 //在栈中创建一个p来强引用此对象Obj 31 Person p=new Person(1); 32 33 //在栈中创建一个weakReference来弱引用此对象Obj 可以获取对象的属性值 34 WeakReference<Person> weakReference=new WeakReference<Person>(p); 35 System.out.println(weakReference.get().getId());//打印输出:1 36 37 //断开p和Obj的强引用 38 p=null; 39 //System.gc(); 40 System.out.println(weakReference.get().getId());//打印输出:1 41 //p=null 之后 还是可以正常的打印输出1 说明断开强引用和其他弱引用,软引用压根没有关系. 42 //如果在打印之前 调用gc() 方法之后 就会报错..java.lang.NullPointerException 43 //垃圾回收不论内存是否不足都会回收只被弱引用关联的对象。 44 45 } 46 47 public static void test3(){ 48 //在堆中创建一个对象Obj 49 //在栈中创建一个p来强引用此对象Obj 50 Person p=new Person(1); 51 52 //Phantom 幻影幽灵 的意思 53 ReferenceQueue<Person> referenceQueue = new ReferenceQueue<Person>(); 54 //在栈中创建一个phantomReference来虚引用此对象Obj 不可以获取对象的属性值 55 PhantomReference<Person> phantomReference=new PhantomReference<Person>(p,referenceQueue); 56 System.out.println(phantomReference.get().getId());//打印报错 java.lang.NullPointerException 57 //直接得不到p对象对应的id值.... 58 //PhantomReference的唯一作用就是 能在这个对象被收集器回收时收到一个系统通知 看test4()方法 59 } 60 61 public static void test4(){ 62 63 //在堆中创建一个对象Obj 64 //在栈中创建一个p来强引用此对象Obj 65 Person p=new Person(1); 66 67 //Phantom 幻影幽灵 的意思 68 ReferenceQueue<Person> referenceQueue = new ReferenceQueue<Person>(); 69 //在栈中创建一个phantomReference来虚引用此对象Obj 不可以获取对象的属性值 70 PhantomReference<Person> phantomReference=new PhantomReference<Person>(p,referenceQueue); 71 72 System.out.println(referenceQueue.poll());//打印输出: null 这个是查询队列中是否有元素. 73 74 //断开p和obj的强引用 75 p=null; 76 System.gc();//p被回收之后 队列referenceQueue中就有值了. 77 78 try { 79 Thread.sleep(1000); 80 } catch (InterruptedException e) { 81 e.printStackTrace(); 82 }//过 一秒钟之后再查询队列中是否有元素. 83 System.out.println(referenceQueue.poll());//打印输出: java.lang.ref.PhantomReference@77fef1a0 84 //PhantomReference的唯一作用就是 能在这个对象被收集器回收时收到一个系统通知 85 //如果这个对象被回收了,会把通知放到队列中. 86 87 //如果前面p=null注释掉 再运行打印输出就是 null 因为p没有被回收(强引用中) 就不会把通知放到队列中...队列中为空 null 88 //回收的标志就是把通知放到队列中.. 89 } 90 } 91 92 class Person{ 93 public Person(Integer id) { 94 this.id = id; 95 } 96 97 private Integer id; 98 99 public Integer getId() { 100 return id; 101 } 102 103 public void setId(Integer id) { 104 this.id = id; 105 } 106 107 @Override 108 protected void finalize() throws Throwable { 109 System.out.println("finalized!!!!!"); 110 } 111 }