前言
学习是一个持久的是,你不能要求他立马给你什么回报,但到达了一定的量级回报自然就有了,
final修饰符
final关键字可以修饰类,方法,变量,用来表示他修饰的类,方法,变量不可变。
- final修饰成员变量
对于final修饰的成员变量来说,一旦有了初始值就不能被重新赋值了,如果在定义的时候没有进行初始化那么变量将一直是系统默认的数值(那就没有意义那因此在定义final 成员变量的时候一定要显示的进行初始化)
成员变量是随着类和对象的初始化而初始化的 当类初始化的时候系统会为类变量分配内存 ,并赋予初始值,当创建对象的时候系统回味对象的实例变量分配内存 并赋予初始值。
public class FinalTest2 {
/**
* 该实例变量会在创建FinalTest2对象的时候会对
* age默认值
*/
final int age;
{
// 此时age还没有初始值 所以会报错
// System.out.println(age+"");
age = 10;
System.out.println(age+"");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new FinalTest2();
}
}
final修饰的类变量的初始化:在静态代码块中进行初始化或者是声明变量的时候进行初始化,而且只能在这两个地的其中一个
final修饰的实例变量的初始化:在非静态代码块中构造器变量声明的处的三处之一进行初始化。
public class FInalTest {
// 声明变量的时候进行初始化
final int a = 6;
final String str;
final int c;
final static double d;
{
// 在静态代码块中对变量进行初始化
str = "hello xiaohei";
// 因为final一旦赋值就不能被修改 所以下边的语法是非法的
// a=9;
}
static {
d =22.4d;
}
public FInalTest() {
c = 12;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
FInalTest test = new FInalTest();
System.out.println(test.a);
System.out.println(test.str);
System.out.println(test.c);
System.out.println(test.d);
}
- final 修饰局部变量
系统不会对局部变量进行初始化,必须由程序员显示的进行初始化,因此final修饰局部变量的时候可以赋予初始值,也可以不赋予初始值,在后边的代码中为他赋值不过只能赋值一次,如果局部变量在定义的时候已经赋予初始值则无法再次赋值。
public class FinalTest3 {
public void test(final String a) {
// 非法语句
// a = 5
System.out.println("" + a);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
/***
* 定义的时候可以进行初始化 final 变量不能重复赋值
*/
final String str = "hello";
/***
* final 变量在没有指定默认值的时候可以进行一次初始化
*/
final double d;
d = 2.3d;
FinalTest3 test3 = new FinalTest3();
test3.test(str);
}
}
final 修饰基本类型变量和引用型变量区别
final修饰基本数据类型的时候在基本数据类型被初始化之后数值就不能在改变。
final修饰引用类型的数据的时候初始化之后保证的是引用指向的地址不变但是地址内部的对象的内容等可以变。
public class FinalTest5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// final 修饰数组变量 air是一个引用变量
final int[] air = {5,6,12,9};
System.out.println(Arrays.toString(air));
// 对数组进行排序
Arrays.sort(air);
System.out.println(Arrays.toString(air));
air[3] =52;
System.out.println(Arrays.toString(air));
// air = null;
}
}
final 变量的宏替换
当定义一个变量的时候为该变量指定了初始值 而且在编译的时候可以通过,那么实质上此变量就是一个宏变量,编译器会把程序中的用到该变量的地都变成实际的数值(final只有在定义的时候就初始化才会是宏变量)
final修饰方法
final修饰的方法表示不能被重写可以被重载, 但是针对于继承来说子类还是可以定义一个一摸一样的方法只不过不是重写。
final修饰类
final修饰一个类表示该类不能被继承。
不可变类
意思是一种类在创建实例之后实例变量是不可改变的 例如 String ,Double等类
创建自定义的不可变的类的原则
- 使用private和final修饰类的成员。
- 提供带参数的构造器对内部的变量直接初始化。
- 仅仅为成员变量提供geter方法 ,因为final变量不能被修改
public class FinalTest6 {
private final String detail;
private final String postCode;
public FinalTest6() {
this.detail = "";
this.postCode = "";
}
public FinalTest6(String detail, String postCode) {
this.detail = detail;
this.postCode = postCode;
}
public String getDetail() {
return detail;
}
public String getPostCode() {
return postCode;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj.getClass() == FinalTest6.class) {
FinalTest6 finaltest = (FinalTest6) obj;
if (this.getDetail() == finaltest.getDetail()) {
return true;
}
}
return false;
}
}
在设计不可变类的时候应该注意内部的成员变量的类型不是引用类型要不然会被修改,就是去了不可变类的意义了。