再释final关键字、浅析java缓存

 

      以前总是遇到一些不可思议的事,但是那是没有时间和精力去解决,只是先记着,唉,记着记着,就有去解释一下的冲动了。

 

引例:

public class FinalKeyWordTest {

	public static void main(String[] args) {
		
		final String str1 = "我是"+ 123;
		
		final String str2 = "我是" +String.valueOf(123);
		
		System.out.println(str1 == "我是123");
		
		System.out.println(str2 == "我是123");
		
	}

}

//运行结果:
//true
//false

//乍一看,为何第一句输出真,而后一句输出假呢?刚开始我也极端纳闷,想不通(不过还没到要跳楼的程度),
//资料查啊查才有“一点”眉目

//总结:首先,我们要清楚“.equals()”方法和“==”的区别,第一句说明了str1和后面的字符串是同一个东西。str1和
//str2没有太大的区别,只是定义str2时显式将数值123转换成字符串,但由于该变量的值需要调用String类方法,因
//此编译器无法编译时确定str2的值,str2不会被当成“宏变量”处理。(但str1会被当成宏变量处理,在编译时就会确
//定值。

 

 

很多人遇到过这种情况,在匿名内部类中使用一个内部类外的局部变量时,如果该局部变量不加final关键字修饰,会编译不通过,这是为什么呢?如果你知道答案,以下内容请勿看,免得浪费你宝贵的时间。

public class InlineClassTest {

	public static void main(String[] args) {

		final String str = "Java";

		new Thread(new Runnable() {

			public void run() {

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

					System.out.println(str + i);

					try {

						Thread.sleep(1000);

					} catch (InterruptedException e) {

						e.printStackTrace();

					}

				}
			}

		}).start();
		
		// 执行到这里,main方法结束,但启动的线程还在运行
		
	}

}

 

 

 小释:如果str变量没有加final,那么当main方法执行结束后,str变量会被回收或被销毁,那么子线程用的str就不存在了,所以Java是不允许这些矛盾出现的,所以此时final关键字就起作用了,该关键字允许内部类产生隐式的“闭包”,闭包将使得局部变量脱离它所在的方法继续存在。

 

 

 

 

附:java缓存小实例:

public class BufferMemory {

	public static void main(String[] args) {

		String str1= "改变世界,下一个就是U";
		
		String str2 = "改变世界,下一个就是U";
		
		System.out.println(str1 == str2);
		
	}

}

 

运行结果:

true

小释:Java会缓存曾经用过的字符串直接量(本人估计这样的机制是想提高运行速度和节省空间吧)。

 

总结:以上都是一些很小的细节,但是,见叶知秋,我们可以从一些小小的细节去窥探java运行机制,其实还是蛮有意思的。

 

计划:研究java集合的实现细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值