三个修饰符:private、static、final。

private:表示属性或者方法是私有的与public、protected对应。public代表公用,其他类或者该类的子类也允许访问被public修饰的属性等;protected代表受保护的,其他类无法访问被protected修饰的属性或者其他东西但是允许该类的子类访问;private代表私有的,不允许除本类之外的其他类访问,包括子类也不允许访问被private修饰的属性或其他。

 static:静态的,static修饰的东西(代码块、属性等)不属于任何对象属于某个类,是对象公有的。static块允许出现在任何地方,但是不允许出现在方法内部。

 final:最终的,也就是不允许修改,一旦赋值后被final修饰的东西就不再允许修改了。final修饰引用变量时,该引用不能改变其引用地址了,但是该引用的属性还是允许修改的。final修饰方法时,被修饰的方法不能够被重写。final修饰的方法比非final方法要快,因为在编译的时候就被静态绑定了,不需要在运行时进行动态绑定。final修饰的类称为final类。通常使用final修饰的类功能是完整的,因为不允许继承(String、Integer等)。

final修饰变量时,该变量在类加载时就会被初始化,会因为对象的创建而创建加载。

static修饰变量时,该变量将只被初始化一次,此后不再重新初始化。

可见,final和static是不同的,一个类中若有着final和static修饰的两个属性,在创建对象时,static修饰的属性只被初始化一次,而final修饰的属性会随着对象的创建而被创建初始化。

看下面代码:

public class Atest {
    private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    private final String fs=sdf.format(new Date());
    private static String ss=sdf.format(new Date());
    public static void main(String[] args) {
        Atest aa=new Atest();
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Atest bb=new Atest();
        System.out.println("aa.fs="+aa.fs);
        System.out.println("aa.ss="+aa.ss);
        System.out.println("bb.fs="+bb.fs);
        System.out.println("bb.ss="+bb.ss);
    }
}

运行结果如下:

可见final修饰的属性fs在线程sleep一秒后因为创建了新的对象所以值变了,而static修饰的变量因为是属于类的所以没有改变。

那么通常我们使用Log打印日志时我们会这样写:

private static final Log log=LogFactory.getLog(Test.class);

这里我们将日志记录器声明为私有、静态、final类型的了。有什么原因呢?首先日志记录器应当是一个类内部的东西,不允许其子类或者其他类使用因此被private修饰为私有的。再其次,对于所有该类的对象也就是该类的所有实例只需要一个logger所以使用static修饰。且logger不能被替换或者修改、所以使用final再做修饰。 

01-13 09:19