final
在Java中声明属性、方法和类时,可使用关键字final来修饰。
final变量即为常量,只能赋值一次;
final方法不能被子类重写;
final类不能被继承。
1. final变量
声明 final 字段有助于优化器作出更好的优化决定,因为如果编译器知道字段的值不会更改,那么它能安全地在寄存器中高速缓存该值。final 字段还通过让编译器强制该字段为只读来提供额外的安全级别。
其初始化可以在两个地方,一是其定义处,也就是说在final变量定义时直接给其赋值,二是在构造函数中。这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时既在定义时给了值,又在构造函数中给另外的值。
一旦被初始化便不可改变,这里不可改变的意思
对基本类型来说是其值不可变,而
对于对象变量来说其引用不可再变。
当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。
另外方法中的内部类在用到方法中的参变量时,此参变也必须声明为final才可使用。
在java中,普通变量系统是自动初始化的,数值变量自动初始化为0,其余类型变量自动初始化为空。但是final类型的变量必须显示初始化,且初始化的方法必须是在申明时或者在构造方法中直接赋值,而不能通过调用函数赋值。
2. final方法
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。
使用final方法的原因有二:
第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌inline机制,大大提高执行效率。
注意,类中所有的private方法都被隐含是final的。由于无法取用private方法,则也无法重载之。
3. final类
final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。
package finalandstatic;
import java.util.Random;
public class Fas {
public static void main(String[] args) {
FinalData fd1 = new FinalData();
FinalData fd2 = new FinalData();
System.out.println(fd1.toString());
System.out.println(fd2.toString());
fd1.v1 = new Value(1);
//fd1.v2= new Value(2);//如果不是基本数据类型,则是不能改变其引用
//fd1.V_3 = new Value(3);
}
public void with(final Value v){
//v = new Value(); final类型参数,不能改变其引用对象
}
public int get(final int v){
//return v++;
return v+1;
}
}
class FinalData{
private final int f = new Random().nextInt(20);
public static final int fs = new Random().nextInt(20);
public Value v1 = new Value(11);
public final Value v2 = new Value(22);
public static final Value V_3 = new Value(33);
@Override
public String toString() {
return "f:"+f+";"+"fs:"+fs;
}
}
class Value{
int i;
public Value(){
}
public Value(int i) {
this.i = i;
}
}
f:15;fs:11
f:9;fs:11
static
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。
static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用--废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。
static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为:
类名.静态方法名(参数列表...)
类名.静态变量名
类名.静态方法名(参数列表...)
类名.静态变量名
用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块(用处非常大,呵呵)。
public class Test5 {
private static int a;
private int b;
static {
Test5.a = 3;
System.out.println(a);
Test5 t = new Test5();
t.f();
t.b = 1000;
System.out.println(t.b);
}
static {
Test5.a = 4;
System.out.println(a);
}
public static void main(String[] args) {
// TODO 自动生成方法存根
}
static {
Test5.a = 5;
System.out.println(a);
}
public void f() {
System.out.println("hhahhahah");
}
}
3
hhahhahah
1000
4
5