package com.company.final01;
/*
* 关于java语言当中Final关键字:
* 1、final是一个关键字,表示最终的,不可变得
*
* 2、final修饰的类无法被继承 public final class A{}
*
* 3、final修饰的方法无法被覆盖 public final void add(){}
*
* 4、final修饰的变量一旦赋值之后,不可重新赋值
*
* 5、final修饰的实例变量:
* 由于实例变量有默认值 + final修饰的变量一旦赋值不能重新赋值
* 综合考虑,java语言最终规定实例变量使用final修饰之后,必须手动初始化赋值,不能采用系统默认值。
*
* 6、final修饰的引用,一旦指向某个对象之后,不能再指向其他对象,那么被指向的对象无法被垃圾回收器回收。
* final修饰的引用指向某个对象后,可以理解为引用变量保存该对象的内存地址,当再指向其他对象后,就会改变* 指向的内存地址,引用变量的值就发生了改变,因此编译会报错。
* 但是final修饰的引用,该引用指向的对象里面的属性是可以修改的,这并没有改变引用指向的内存地址的值。
*
* 7、【注】final修饰的实例变量是不可变的,这种变量一般和static联合使用,被称为“常量”,这样既可以保证不被改变,又能节约内存。
* 常量定义语法格式:
* public static final 类型 常量名 = 值;
* java规范中要求所有常量的名字全部大写,每个单词之间使用下划线连接。
* public static final String GUO_JI = "中国";
* */
public class FinalTest01 {
// 下面程序编译时报错
/*
final int i ;
i= 10;
*/
// 实际上两种方案一样,因为方案一实例变量赋值运算是在构造方法执行的时候才会做。
// 所以将赋值操作写在构造器中本质上是一样的。
// 第一种解决方案
final int i = 10;
// 第二种解决方案
final int num;
public FinalTest01(){
this.num = 200;
}
public static void main(String[] args) {
final int age; // 编译通过
age = 10;
// age = 20; 编译报错
// 创建用户对象
User u = new User("111");
// 又创建了一个新的User对象
// 程序执行到此处表示以上对象已变成垃圾数据,等待垃圾回收器的回收
u = new User("222");
final User user = new User("111");
// user = new User("222"); 编译报错
user.setId("50"); // 这个没有报错
// 终其原因:引用本质上是保存对象的地址,被final修饰之后,只要地址没有改变就可以了,对象内部变量的改变并不会影响。
}
}
package com.company.final01;
public class User {
private String id;
public User() {
}
public User(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}