Java中关于WeakReference和WeakHashMap的理解
新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下:
 private static String test(){
         String a = new String("a");
         WeakReference<String> b = new WeakReference<String>(a);
         WeakHashMap<String, Integer> weakMap = new WeakHashMap<String, Integer>();
         weakMap.put(b.get(), 1);
         a = null;
         System.gc();
         String c = "";
         try{
             c = b.get().replace("a", "b");
             return c;
         }catch(Exception e){
             c = "c";
             return c;
         }finally{
             c += "d";
             return c + "e";
         }
     }
运行结果是“cde”。
该题关键在考察WeakReference和WeakHashMap的理解。
先说下一点Java GC内容
在Java里, 当一个对象object被创建时,它被放在Heap里。当GC运行的时候,如果发现没有任何引用指向object,object就会被回收以腾出内存空间。或者换句话说,一个对象被回收,必须满足两个条件:1)没有任何引用指向它 2)GC被运行.
WeakReference
当一个对象仅仅被weak reference(弱引用)指向, 而没有任何其他strong reference(强引用)指向的时候, 如果GC运行, 那么这个对象就会被回收。weak reference的语法是:
WeakReference<T> weakref = new WeakReference<T>();
当要获得WeakReference的object时, 首先需要判断它是否已经被GC回收,若被收回,则下列返回值为空:
weakref.get();
所以在上述代码中,经过a=null; System.gc()后,在WeakReference<String> b = new WeakReference<String>(a);中a为空已经被系统收回了,而b已经没有强引用指向了,所以b也被系统GC收回了。所以当代码运行到c = b.get().replace("a", "b");时,由于b.get()为null,会抛出异常。
WeakHashMap
WeakHashMap其实和HashMap用法类似,它们之间唯一的区别就是:HashMap中的key保存的是实际对象的强引用,因此只要对象不被销毁,即该key所对应的key-value都不会被垃圾回收机制回收。但是WeakHashMap保存的实际对象是弱引用,这意味着只要该对象没有被强对象引用就有可能会被垃圾回收机制回收对应的Key-value。示例如下:
import java.util.WeakHashMap;  
public class WeakHashMapTest {
    public static void main(String[] args) {
        WeakHashMap w= new WeakHashMap();
        //三个key-value中的key 都是匿名对象,没有强引用指向该实际对象
        w.put(new String("语文"),new String("优秀"));
        w.put(new String("数学"), new String("及格"));
        w.put(new String("英语"), new String("中等"));
        //增加一个字符串的强引用
        w.put("java", new String("特别优秀"));
        System.out.println(w);
        //通知垃圾回收机制来进行回收
        System.gc();
        System.runFinalization();
        //再次输出w
        System.out.println("第二次输出:"+w);
    }
}  
输出结果:{java=特别优秀, 数学=及格, 英语=中等, 语文=优秀}
      第二次输出w:{java=特别优秀}
所以在最开始的代码中WeakHashMap<String, Integer> weakMap = new WeakHashMap<String, Integer>(); weakMap没有强引用指引,所以在执行System.gc()后weakMap被系统GC收回。
打印出代码中的变量
 private static String test(){
         String a = new String("a");
         //System.out.println(a);
         WeakReference<String> b = new WeakReference<String>(a);
         //System.out.println(b.get());
         WeakHashMap<String, Integer> weakMap = new WeakHashMap<String, Integer>();
         weakMap.put(b.get(), 1);
         a = null;
         System.out.println("GC前b.get():"+b.get());
         System.out.println("GC前weakMap:"+weakMap);
         System.gc();
         System.out.println("GC后"+b.get());
         System.out.println("GC后"+weakMap);
         String c = "";
         try{
             c = b.get().replace("a", "b");
             System.out.println("C:"+c);
             return c;
         }catch(Exception e){
             c = "c";
             System.out.println("Exception");
             return c;
         }finally{
             c += "d";
             return c + "e";
         }
     }
运行后结果为:
GC前b.get():a
GC前weakMap:{a=1}
GC后null
GC后{}
Exception
cde
可见,在System.gc()前后的WeakReference和WeakHashMap的变化。
Java中异常处理中try,catch,finally的关系
java 的异常处理中,
在不抛出异常的情况下,程序执行完 try 里面的代码块之后,该方法并不会立即结束,而是继续试图去寻找该方法有没有 finally 的代码块,
如果没有 finally 代码块,整个方法在执行完 try 代码块后返回相应的值来结束整个方法;
如果有 finally 代码块,此时程序执行到 try 代码块里的 return 语句之时并不会立即执行 return(如果return后是语句或者函数,eg:return b+=10; or return functionA();,先执行return后的语句或者函数),而再去执行 finally 代码块里的代码,
若 finally 代码块里没有 return 或没有能够终止程序的代码,程序将在执行完 finally 代码块代码之后再返回 try 代码块执行 return 语句来结束整个方法;
若 finally 代码块里有 return 或含有能够终止程序的代码,方法将在执行完 finally 之后被结束,不再跳回 try 代码块执行 return。
在抛出异常的情况下,原理也是和上面的一样的,你把上面说到的 try 换成 catch 去理解就 OK 了。
现在分析上述代码:
System.gc()后b.get()和weakMap均为null
try中抛出异常,在catch中捕获异常
执行c = "c",执行到return c,但是并不立即return,执行finally
执行 c +="d"; return c + "e",finally代码块中有return语句就不会返回catch中执行return了。
所以最终结果是return "cde"
Java中关于WeakReference和WeakHashMap的理解的更多相关文章
- 【转】Java中关于WeakReference和WeakHashMap的理解
		
新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下: private static String test(){ String a = new String("a&quo ...
 - 关于Java中语句符号及格式的理解
		
关于Java中语句符号及格式的理解 这篇文章是撰写的第一篇文章,在此作一下博主是一名在读的工科研究生,种种原因,研二开始决定转行从事程序员工作.开始的自学之路并不算非常顺畅,也走了一点弯路,但一直都坚 ...
 - Java中关于static语句块的理解
		
Java中关于static语句块的理解 一.static块会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法. 实例一 public class A{ String name ...
 - Java中常用的设计模式代码与理解
		
Java中常用的设计模式代码与理解 一.单例模式 1.饿汉式 (太饿了,类加载的时候就创建实例) /** * 饿汉式单例模式 */ public class HungrySingleInstance ...
 - Java中的 WeakReference 和 SoftReference
		
我们知道Java语言中没有指针,取而代之的是引用reference.Java中的引用又可以分为四种:强引用,弱引用(WeakReference),软引用(SoftReference),虚引用(Phan ...
 - java中set和get方法的理解
		
对于JAVA初学者来说,set和get这两个方法似乎已经很熟悉了,这两个方法是JAVA变成中的基本用法,也是出现频率相当高的两个方法. 为了让JAVA初学者能更好的理解这两个方法的使用和意义,今天笔者 ...
 - 谈谈java中的WeakReference
		
Java语言中为对象的引用分为了四个级别,分别为 强引用 .软引用.弱引用.虚引用. 本文只针对java中的弱引用进行一些分析,如有出入还请多指正. 在分析弱引用之前,先阐述一个概念:什么是对象可到达 ...
 - Java中==与equals的区别及理解
		
区别: "==" 比较的是两个引用在内存中指向的是不是同一对象(即同一内存空间),也就是说在内存空间中的存储位置是否一致. 如果两个对象的引用相同时(指向同一对象时)," ...
 - Java中char和String 的深入理解 - 字符编码
		
开篇 https://blog.csdn.net/weixin_37703598/article/details/80679376 我们并不是在写代码,我们只是将自己的思想通过代码表达出来! 1 将思 ...
 
随机推荐
- Android 学习笔记之如何使用SQLite数据库来保存数据...
			
PS:最近一阵子都在为考试复习...坑爹的计算机网络,复习了3天,最后该不会的还是不会...明天还考英语...真蛋疼... 学习内容: 1.使用SQLite数据库来保存数据... SQLite: ...
 - mac ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
			
好久不用mysql,今天突然想用的时候, mysql -uroot -p 直接报了下面的错误 ERROR 2002 (HY000): Can't connect to local MySQL serv ...
 - mysql 行锁一则
			
CREATE TABLE `t1` ( `id` int(11) NOT NULL DEFAULT '0', `name` varchar(20) DEFAULT NULL, PRIMAR ...
 - 12 19 spring3 项目总结
			
项目截图: 林集团 https://home.cnblogs.com/u/linjituan/ 团队guihub: https:///github.com/MoiGi 李鹏飞 https://www. ...
 - 前端自动化工具 -- Gulp 使用简介
			
gulp是基于流的前端自动化构建工具. 之前也谈到了 grunt的用法,grunt其实就是配置+配置的形式. 而gulp呢,是基于stream流的形式,也就是前一个函数(工厂)制造出结果,提供后者使用 ...
 - C#设计模式——外观模式(Facade Pattern)
			
一.概述 在系统设计中,某一个系统可能非常庞大,用户要使用该系统就不得不掌握大量的接口,造成使用的不便.这时可以考虑将该系统细分成一系列子系统并使子系统间的耦合降到最低,利用外观模式提供一个外观对象, ...
 - MVC应用程序结构与规划
			
对MVC好长一段时间练习,说句实在的话,还有很多是感到陌生,很多是生疏...... 很多网友也是刚想学习MVC,看到Insus.NET每学习一种方法,一个技巧均写成博文,也很希望能获取到练习的源程序以 ...
 - Winform开发框架之权限管理系统改进的经验总结(1)-TreeListLookupEdit控件的使用
			
最近一直在做一些技术性的研究和框架改进工作,博客也落下好几天没有更新了,也该是时候静下心来,总结这段时间的一些技术改进的经验了.和上一阶段的CRM系统开发和技术研究一样,我都喜欢在一个项目或者模块完成 ...
 - vmware安装mac
			
1.笔记本安装mac10.6 2.用VMware8,需要在mac.vmx中添加以下语句 guestOS = "darwin10"ich7m.present="TRUE&q ...
 - ExtJs4 笔记(4) Ext.XTemplate 模板
			
ExtJs4 笔记(4) Ext.XTemplate 模板 摘自:http://www.cnblogs.com/lipan/ 本篇将涉及到ExtJs中一个重要的概念,模板.话说Razor很神奇,但是我 ...