6、关于final,常量池,宏替换

1、finally比较类似c/c++里的const,final 定义一个变量必须指定一个初始值,但是可以不用一定在声明的同时初始化。

比如:

class Fll
{
	final int a;
	{
		a = 1;
	}
}

在初始化块中,或者在显式构造器中对final修饰的变量初始化是可以的。而初始化之前不能使用,

比如:

class Fll
{
	final int a;
	{
		System.out.println(a);
		a = 1;
	}
}
写出来就会被报错。

2、final修饰的变量是不可以改变的,但是对于引用变量来说,自身的值只是相当于一个“指针”,是堆中的地址值。所以引用变量的具体值是可以改变的。

比如:

public class FinalTest {
	public static void main(String[] args)
	{
		final int[] intArry = {4,2,3,1};
		<strong>Arrays.sort(intArry);
	      intArry[2] = 11;</strong>
		System.out.println(Arrays.toString(intArry));
	}

}

是可以的,但是

public class FinalTest {
	public static void main(String[] args)
	{
		final String str = "final";
		str = "final2"
	}
}

是不可以的,“final”和“final2”是常量池中的两个字符串,地址不同,上面代码相当于改变了str的地址值,即str本身。


3、final的宏替换

看如下代码:

public class FinalTest {
	public static void main(String[] args)
	{
		String str = "final";
		String str2 = "test";
		String s1 = "finaltest";
		String s2 = str + str2;
		System.out.println((s1 == s2));
	}
}

结果是false,因为编译时s1指向常量池中的“finaltest”字符串,而s2不能确定,s2需要运行时才能确定,所以s2不指向常量池中的字符串。这也说明常量池是在编译时确定的。常量,或者也叫直接量,当一个变量被final修饰定义时就指定了值并且值可以在编译时就被确定,满足这三个条件变量就变成了宏替换的直接量


给str1和str2加上final修饰。

public class FinalTest {
	public static void main(String[] args)
	{
		final String str = "final";
		final String str2 = "test";
		String s1 = "finaltest";
		String s2 = str + str2;
		System.out.println((s1 == s2));
	}
}
结果会输出true,


注意:如果没有str和时str2之间的加法运算,情况有所不同:

public class FinalTest {
	public static void main(String[] args)
	{
		String str = "final";
		//String str2 = "test";
		String s1 = "final";
		String s2 = str;
                //String s2 = str + "";
		System.out.println((s1 == s2));
	}
}
此时会输出true

如果给str加上一个空字符串再赋给s2

public class FinalTest {
	public static void main(String[] args)
	{
		String str = "final";
		//String str2 = "test";
		String s1 = "final";
		//String s2 = str;
                String s2 = str + "";
		System.out.println((s1 == s2));
	}
}
此时会输出false


说明结论:如果一个字符串指向常量池中的常量,在把这个String赋值给其他String2,在编译时编译器会把String2也指向同一个常量。而当有加法运算(或者任意运算)在给String时候,编译时编译器肯定不知道(或者不尝试检查)运算结果,所以即使运算结果和常量池中某一常量是一样的,也不会把String指向常量。

                     需要注意只有引用类型才有这种情况,对于基本数据类型则没有这种问题,两个数相等就是相当。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值