final这个关键字从学Java开始就有提及。它可以用来修饰class, method, method parameter,variable等。这里主要说说最后这一种。
对于有final 修饰的variable, 无论是instance variable 还是local variable, 其含义是说(一般)一经初始化和赋值,其值就无法改变。这里,对于instance variable, 我们说,这“初始化和赋值”可能是在声明时就完成的,也可以是在构造函数中完成的。
然而,这个一般无法改变的值却是可以改变的。在JSR 133 中提到了用反射改变final 的instance field 的方法。这里截取的是那里面的例子:
classA...{
finalintx;
A()...{
x=1;
}
intf()...{
returnd(this,this);
}
intd(Aa1,Aa2)...{
inti=a1.x;
g(a1);
intj=a2.x;
returnj-i;
}
staticvoidg(Aa)...{
//usesreflectiontochangea.xto2
}
}
在JDK1.4 以及它以前的版本中,这种方法是行不通的。而在JDK 5 中,这种方法却可行的。具体做法是分别调用Field 的setAccessible(true) 方法和setX 方法进行赋值。
但是,这种方法可能会因为reorder 导致问题。JSR133 中说到:
... Another problem is that the semantics is designed to allow aggressive optimization of final fields.
Within a thread, it is permissible to reorder reads of a final field with calls to methods that may
change final fields via reflection.
所以,在JSR 133 中,提出了Final Field Safe Context 的概念。这个名词的意思是,在这个context 中,可以保证不会发生reorder 的现象。但奇怪的是,现在JVM 的实现中,似乎没有为这个语义定义关键字。
说到final, 顺便说一下static final. static final 在类初始化以后,几乎都不能改变。这里说“几乎” 的原因是有例外:
Static final fields may only be modified in the class initializer that defines them, with the exception
of the java.lang.System.in, java.lang.System.out, and java.lang.System.err static fields, which can be modified by the java.lang.System.setIn, java.lang.System.setOut, and java.lang.System.setErr methods.
另外,顺便说一下,对于有无static 修饰的final field, 其在JVM 内部的初始化函数是不同的。这个有兴趣的可以看一下后面的参考文档。
最后要说的是所谓值“不能改变”的意思。概括的说,对于primitive 类型的变量,一旦声明为final, 除了上面的情况,初始化后就不能改了。而对于对象类型的field, “不能改变”的是它的引用。要理解这句话的意思,请看一下这段代码:
packagecom.dproxy;
importjava.util.ArrayList;
publicclassFinalChangeTest{
publicfinalinta=3;
publicfinalObjectb=null;
publicfinalStringc="abc";
publicfinalStringBufferd=newStringBuffer("a");
publicfinalArrayListe=newArrayList();
publicfinalTestClassf=newTestClass();
publicfinalint[]g=newint[3];
publicstaticvoidmain(Stringargs[]){
FinalChangeTesttest=newFinalChangeTest();
//test.a=4;//error
//test.b="";//error
//test.c="";//error
//test.d=test.d.append("ttt");//error
test.d.setCharAt(0,'c');
test.e.add("");
//System.out.println(test.f.i);//1
test.f.i=2;
//System.out.println(test.f.i);//2
test.g[0]=3;
}
classTestClass{
publicinti=1;
}
publicvoidfinalVarTest(){
finalinta=3;
finalObjectb=null;
finalStringc="abc";
finalStringBufferd=newStringBuffer("a");
finalArrayListe=newArrayList();
finalTestClassf=newTestClass();
finalint[]g=newint[3];
//a=2;//error
//b="";//error
//c="";//error
d.setCharAt(0,'c');
e.add("");
f.i=0;
g[1]=2;
}
}
上面代码里注释部分的句子都是无法通过编译的。对比这个,读者可以理解一下。
参考:
JSR133
http://www.cs.umd.edu/~pugh/java/memoryModel/archive/2398.html
http://dev2dev.bea.com.cn/bbsdoc/20060704286.html
分享到:
相关推荐
阿里巴巴要开发云计算!讲述云计算的含义!说说云计算
自己写一个小程序,我在java1.6.0_10;smslib-v3.4.5下运行成功,主要是以下几个类. Level_Final_Serial.java:串口底层操作 ...http://blog.csdn.net/yangzl0123/archive/2010/03/02/5339263.aspx说说您的看法).
enum实现 JDK5中提供了Java枚举类型的实现,与其说是一种新类型,... public final class Season extends Enum { public static Season[] values() { return (Season[])$VALUES.clone(); } public static Season
10 使用final关键字修饰一个变量时 是引用不能变 还是引用的对象不能变 11 11 " "和equals方法究竟有什么区别 11 12 静态变量和实例变量的区别 12 13 是否可以从一个static方法内部发出对非static方法...
3、说说&和&&的区别。 4、在JAVA中如何跳出当前的多重嵌套循环? 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么...
http://blog.csdn.net/yangzl0123/archive/2010/03/02/5339263.aspx说说您的看法). 时间:2010-3-3 12:15 ********************************************************************** smslib版本已经更新:...
Q1:简单说说Java有哪些数据类型 答:①分为基本数据类型和引用数据类型。②基本数据类型包括:数值型(byte、short、int、long、float、double),字符型(char)以及布尔型(boolean)。除了基本类型外,其他数据...
final 修饰符的理解 说说你对泛型的理解 泛型中 extends 和 super 的区别 描述下 Java 中的异常处理机制 什么是 HashMap,描述下其实现原理 HashMap、Hashtable 和 HashSet 这三者有什么联系和区别 列举下 Java 的...
上章讲了访问控制符,这章开始讲非访问控制符。 java中的非访问修饰符的作用各不一样,据我所知常用的有六种: static final abstract ...首先我们来说说static: 被static修饰的方法我们称为静态方
6、final,finally,finalize的区别 7、Serializable 和Parcelable 的区别 8、静态属性和静态方法是否可以被继承?是否可以被重写?以及原因? 9、成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及...
EXAPI是完全开源的,可以随意使用(不过似乎要设置一下ZLIB和LIBPNG相关的一些林林总总东东,据说说调试版本需要忽略特定库libcmt.lib等),如果大家发现有什么BUG或有什么帮助改进API的想法可以联系我对于VS2015...
3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有...
3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有...
3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有...
3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有...
【基础】final, finally, finalize的区别 24 【基础】Java 中定义常量的几种方法 25 【基础】什么时候使用字节流?什么时候用字符流? 26 【基础】GBK与UTF-8的区别 26 【基础】static、final、const的区别 26 final...
3、说说&和&&的区别。 4、在JAVA中如何跳出当前的多重嵌套循环? 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有...
3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 9 6、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有...