final可以用来修饰的结构:类,方法,变量
final用来修饰一个类,此类不能被继承,比如String类,System类,StringBuffer类
final用来修饰方法,标识此方法不能被重写,比如Object类中的getClass();方法
final用来修饰变量:此时的变量称为常量,变量具体又分为属性和局部变量:
- final修饰属性:可以考虑赋值的位置有:
- 显示初始化,不能直接写成 final int width;width得赋一个值----final int width = 4;
- 代码块中初始化
- 构造器中初始化,每个构造器中都得对这个final变量赋值否则程序报错,在方法中给final属性赋值时不行的(final修饰的变量必须赋初值,不调用该方法则final变量就没法赋值,就会报错)
- 构造器时对象出生的最后一道关卡,构造器调完以后说明对象创建好了,对象已创建好说明属性已经加载好了,这时候属性就得有值了,我们通过对象调方法,只是说可以对属性的值进行修改,在堆空间中放的属性变量被final修饰以后就是常量就不能考虑修改的事情了,所以被final修饰的变量,跟随着构造器创建出来之后再堆空间中已经出现了,就得告诉我是什么值了,不能被修改了优先于方法的创建。
不能再方法中对final修饰的变量赋值
再构造器中可以给用final修饰的属性赋值
public class FinnalTest {
final int WIDTH = 0;
final int LEFT;
final int RIGHT;
{
LEFT = 8;
}
public FinalTest(){
RIGHT = 2;
}
public FinalTest(int n){
RIGHT = n;
}
}
没有给被final修饰的变量赋值则会报错
在一个构造器中给变量进行了赋值 ,那么在其他的构造器中也得给相同的变量赋值,赋值可以不同。不同的构造器中可以给用final关键字修饰的变量赋不同的值。
如果每个对象的属性不一样,就到构造器中去赋值,如果大家的值都一样可以显示的赋值。
final修饰局部变量(方法内定义的变量、形参)
final修饰局部变量在用的时候就给他赋值,局部变量只声明不初始化不会报错,但是在使用之前一定要赋值
public class FinalVar{
final static int a = 0;//在声明的时候就哟啊赋值,或者在惊天代码块中赋值
/**
static{
a = 0;
}
*/
final int b = 0;//在声明的时候就需要赋值或者在代码块中进行赋值,或者构造器中进行赋值
/**
{
b = 0;
}
*/
public static void main(String[] ars) {
final int LACAL; //局部变量只声明没有初始化,不会报错,与final无关
LACAL = 0;//但是在使用之前一定要初始化赋值
//LACAL = 1;//但是不会允许第二次赋值
}
}
static final 可以用来修饰他俩共同能修饰的结构,static关键字可以修饰属性,方法 代码块,内部类。final可以修饰类,方法,(属性)变量,所以static final可以修饰属性和方法
类的属性赋值位置有哪些?先后顺序如何?
- 默认初始化
- 显示初始化 ,代码块中初始化
- 构造其中初始化
- 通过对象.属性或者对象.方法进行赋值
为什么局部内部类和匿名内部类只能访问局部final变量?
局部内部类和匿名内部类在编译的时候会生成两个class文件,里面的class不会随着外面的class的回收而回收。
当外部类的方法执行完成后,局部变量就会被销毁,但是内部类对象可能还存在对外部类变量的的引用,这个过程JVM底层会将引用的局部变量复制一份,放到内部类里面作为一个成员变量,但是在复制的过程中是不能保证复制的变量是一样的,因此将局部变量设置为final,对其初始化后就不让你再去修改这个变量,使得局部变量与内部类内简历的拷贝保持一致性。