1.final变量
final变量定义:final变量一经初始化就不能再指向其它对象。
在C++中它是一个const指针,而不是指向const变量的指针,const指针的意思是说它只能一直指向初始化时的那个地址,但那个地址中对象本身是可以修改的。而指向const变量的指针是说对象本身是不能修改的。
/**
* StringBuffer是引用对象,
* 如果说是String | int 等基本类型的话 final之后就是常量,没有指向一说
*/
final StringBuffer ss = new StringBuffer("Aaaaa");
ss = new StringBuffer("Bbbbb"); // 错误 ss 不能再指向其它对象
ss.append("Ccccc"); // 正确 ss指向的对象本身可以修改
* final局部变量:可以先声明再初始化,但是没必要,一般都是声明处初始化。
final int a = 1;
* final成员变量:只能在声明处 | 构造函数里 赋值
// 声明处
final int a = 0;
final int b;
// 构造函数
public test() {
b = 1;
}
*final方法参数变量:防止参数在方法体中被修改【其中修改引用类型的话,会影响到函数外面的值】
作用等同于用参数初始化了一个final局部变量。
void testFinalParram() {
int a = 0;
testInt(a);
StringBuffer ss = new StringBuffer("aaaaaa");
testInt(ss);
// 输出aaaaaabbbbb 即使使用了final 还是修改了引用类型的值,只是不能重新赋值而已。
// 这也说明了基本数据类型参数是按值传递,会生成一个副本
// 而引用类型传递是引用类型的地址,地址是不会改变的,但是地址指向的值却可以修改。
DBG.plog(ss.toString());
}
// final基本数据类型 方法参数参数
public void testInt(final int param) {
// param = 1; // 不能修改
}
// final引用类型 方法参数参数
public void testInt(final StringBuffer ss) {
// ss = new StringBuffer(); // 不能重新指向新的实例
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ss.append("bbbbb"); // 但是可以内容
}
// 等同于
// final基本数据类型 方法参数参数
public void testInt1(int param) {
final int param1 = param;
// param = 1; // 不能修改
}
// final引用类型 方法参数参数
public void testInt1(StringBuffer ss) {
final StringBuffer ss1 = ss;
// ss1 = new StringBuffer(); // 不能重新指向新的实例
ss1.append("1111"); // 但是可以内容
}
2.final方法
1.可以被继承,但是不能被子类的方法覆盖和修改。
【不能出现在子类中,但是能被子类调用】
2. 优化效率,可以被编译器内联处理
【具体内部不内联是JVM决定的,另外我们可以自己来实现内联,GL的GLASM.jar就可以实现---InlineAllFinalWrapperFunc】
3.final类
1.不能被继承 所有的方法默认都是final