在Java中这几个关键字常常被混用。

可修饰部分

static:成员变量、方法、代码块(静态代码块)、内部类(静态内部类)
final: 类、成员变量、方法、局部变量

final具体修饰
  1. final 修饰变量
  • 基础类型 用fianl修饰后就变成了一个常量,不可以重新赋值。
  • 包装类型 用final修饰后该变量指向的地址不变,但是该地址的的变量完全可以改变。
  1. final 修饰方法
  • 使用final修饰方法以后,该方法不可被重写
  • 使用final修饰方法在一定程度上可以提升一点效率。
  1. final 修饰类
  • final修饰类该类不可以被继承
static具体修饰

简言之,static的主要作用是:方便在没有创建对象的情况下来进行调用(方法/变量)。

  1. static方法:静态方法不用依赖任何对象就可以进行调用,它是没有this的概念的,另外,静态方法不可以调用非静态变量和非静态方法,因为静态不依赖对象,而普通方法变量依赖对象。
  2. static变量:static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化。
  3. static代码块:static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
    为什么说静态代码块可以优化效率?看下面两段代码:
class Person{
    private Date birthDate;

    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }

    boolean isBornBoomer() {
        Date startDate = Date.valueOf("1946");
        Date endDate = Date.valueOf("1964");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

上面这段代码每次调用isBornBoomer这个方法的时候都会生成startDateendDate 这两个对象,造成空间的浪费。
换成下面这种写法,稍微的会优化一点效率。

class Person{
    private Date birthDate;
    private static Date startDate,endDate;
    static{
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
    }

    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }

    boolean isBornBoomer() {
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}
  1. 静态内部类:
static final 和 final static

两者没有区别,但是习惯于将static写在前面。

那么static final 和 单纯的final有什么区别呢?
final在一个对象类唯一,static final在多个对象中都唯一;

END