1.static
修饰变量:变量随着类的加载完成初始化,内存中只有一个,所有的类共享变量
修饰方法:类加载的时候就存在,不依赖任何实例,static方法必须被实现,不能用abstract修饰。
修饰代码块:在类加载完之后就会执行代码中的内容。顺序:父类静态代码块->子类静态代码块->父类非静态代码块->父类构造方法->子类非静态代码块->子类构造方法。
深入分析Java中的关键字static 这个写得很详细
2.final
修饰变量:
final定义的变量相当于常量,命名使用大写和下划线,声明时赋值或者在构造函数中赋值。
final doublie PI = 3.14;
final修饰对象的引用,包括数组。对象引用不可以改变指向其他对象。但是对象本身的值可以修改。创建对象时初始化。
static final 修饰的变量占据一段改变的存储空间,装载时初始化而不是创建对象时初始化。故任何时候值都不变,都是声明时赋的值。
修饰方法:
不能被子类重写,private 修饰的方法不能被子类访问,也无法重写,所以不能够出现同名方法。而private final修饰的父类方法却可以在子类中重新定义同名函数,貌似可以被重写,但实际是生成了新的方法。
修饰类:
类不能被继承,所有的方法都隐式地设置为final形式,但是final类中的成员变量可以定义为final或者非final形式,就是默认可以修改。
修饰形参:
在方法中不可以更改参数引用所指向的对象
参考:JAVA中static和final的区别
3.static final
和final static没什么区别,一般static写在前面。static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。
static final修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问。如果把常量设置为static final,则真正的不可改。而定义为final的常量实际不是恒定不变的,每次运行可以重新设定,而static final形式则是在装载时初始化的不是创建对象时初始化的。下面例子中out.println(data)执行两次,i4的值发生了变换,但是i5没有发生变换。
static final也可以修饰方法,表示该方法不能重写,可以在不new对象的情况下调用。
public class FinalData{
static Random rand = new Random();
private final int VALUE_1=9; //声明一个final常量
private static final int VALUE_2= 10; //声明一个static、final常量
private final Test test = new Test(); //声明一个final引用
private Test test2 = new Test(); //声明一个不是final的引用
private final int[] a={1,2,3,4,5,6};
private final int i4 = rand.nextInt(20);
private static final int i5 = rand.nextInt(20);
public String toString(){
return i4+" "+i5+" ";
}
public static void main(String[] args) {
FinalData data = new FinalData();
data.test.i = 2; //可以对final引用中的成员变量赋值
// data.test = new Test(); //但不可以把final引用指向其他引用
// data.VALUE_2++; //不能改变final常量值
data.test2 = new Test(); //可以把非final引用指向其他引用
// for (int i = 0; i < data.a.length; i++) {
// a[i]=9; // 不能改变定义为final的数组赋值
// }
out.println(data);
out.println("data2");
out.println(new FinalData());
out.println(data);
}
}
结果:
19 2
data2
2 2
19 2