弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统北村是否足够,总会回收该对象所占用的内存。当然,并不是说当一个对象只有弱引用时,它就会立即被回收-正如那些失去引用的对象一样,必须等到系统垃圾回收机制运行时才会被回收。

import java.lang.ref.SoftReference;

import java.lang.ref.WeakReference;

 

 

public class WeakReferenceTest {

    public static void main(String[] args){

      Stringstr = newString("Java");

      Stringstr1 = newString("Java");

      SoftReference<String>sr = newSoftReference<String>(str1);

      WeakReference<String>wr = newWeakReference<String>(str);

      str= null;

      str1= null;

      System.out.println(sr.get());

      System.out.println(wr.get());

      System.gc();

      System.runFinalization();

      System.out.println(sr.get());

      System.out.println(wr.get());

    }

}

Output:

Java

Java

Java

null

 

不要使用String str = “Java”;这样就看不到运行效果,因为采用这样定义的字符串系统会缓存这个字符串直接量(会使用强引用来引用它),系统不会回收被缓存的字符串常量。

弱引用具有很大的不确定性,因为每次垃圾回收机制执行时都会回收弱引用的对象,而垃圾回收机制的运行又不受程序员的控制,因此程序获取弱引用所引用的Java对象时必须小心空指针异常-通过弱引用所获取的Java对象可能是null.

由于垃圾回收的不确定性,当程序希望从弱引用中取出被引用对象时,可能这个被引用对象已经被释放了。如果程序需要使用那个被引用的对象,则必须重新创建新对象。

public class WeakReferenceTest {

    public static void main(String[] args){

      Stringstr = newString("Java");

      Stringstr1 = newString("Java");

      SoftReference<String>sr = newSoftReference<String>(str1);

      WeakReference<String>wr = newWeakReference<String>(str);

      str= null;

      str1= null;

      System.out.println(sr.get());

      System.out.println(wr.get());

      System.gc();

      System.runFinalization();

      if(wr.get() == null){

            str= new String("Java");

            wr= newWeakReference<String>(str);

            System.out.println(wr.get());

      }

      System.out.println(sr.get());

      System.out.println(wr.get());

    }

}

Output:

Java

Java

Java

Java

Java


 

与weakReference功能类似的还有WeakHashMap,当程序有大量的java对象需要使用弱引用来引用时,可以考虑使用weakHashMap来保存它们。

import java.util.WeakHashMap;

 

class CrazyKey{

      String name;

      public CrazyKey(String name){

            this.name =name;

      }

      public inthashCode(){

            return name.hashCode();

      }

      public boolean equals(Object obj){

            if(obj==this){

                  returntrue;

            }

            if(obj!=null && obj.getClass() == CrazyKey.class){

                  returnname.equals(((CrazyKey)obj).name);

            }

            returnfalse;

      }

      public String toString(){

            return "CrazyKey[name=" + name +"]";

      }

}

 

public class WeakHashMapTest {

    public static void main(String[] args)throws InterruptedException{

      WeakHashMap<CrazyKey,String>map = newWeakHashMap<CrazyKey,String>();

      for(int i=0;i<10;i++){

            map.put(new CrazyKey(i+1+""),"value"+(i+11));

      }

      System.out.println(map);

      System.out.println(map.get(new CrazyKey("2")));

      System.gc();

      Thread.sleep(50);

      System.out.println(map);

      System.out.println(map.get(new CrazyKey("2")));

    }

}

Output:

{CrazyKey[name=8]=value18,CrazyKey[name=9]=value19, CrazyKey[name=4]=value14, CrazyKey[name=5]=value15,CrazyKey[name=6]=value16, CrazyKey[name=7]=value17, CrazyKey[name=10]=value20,CrazyKey[name=1]=value11, CrazyKey[name=2]=value12, CrazyKey[name=3]=value13}

value12

{}

null

 

在垃圾回收机制运行之前,WeakHashMap的功能与普通HashMap并没有太大的区别,它们的功能相似。但一旦垃圾回收机制被执行,WeakHashMap中所有key-value就都会被清空,除非某些Key还有强引用在引用它们。