1. static关键字
    Static关键字有四种使用情况:成员变量、成员方法、代码块、内部类。
    Static修饰的成员变量就成了类变量,随着类的加载而加载,生命周期和类一样。Static修饰的成员方法变成了类方法,可以直接通过类名调用。和.class一样存在于方法区。
    static变量和static方法可以被继承但是不能被重写(没有重写的概念)。static方法可以重载(静态不静态和重载不重载没关系)。不能在成员方法内部定义static变量
    static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法。
    非静态的成员方法与成员变量的调用,只能通过创建对象调用。类名.方法名等;而静态的成员可以通过类名和创建对象调用(尽量用类名调用,不要创建对象)。
    代码一:
class SSClass {
    static {
        System.out.println("SSClass");
    }
}
class SuperClass extends SSClass {
    static {
        System.out.println("SuperClass init");
    }
    public static int value = 123;
    public SuperClass() {
        System.out.println("init SuperClass");
    }
}
class SubClass extends SuperClass {
    static {
        System.out.println("SubClass init");
    }
    public SubClass() {
        System.out.println("init SubClass");
    }
}
public class NotInitialization {
    public static void main(String[] args) {
        System.out.println(SuperClass.value);
        System.out.println(SubClass.value);
        SubClass.value = 789;
        System.out.println(SuperClass.value);
    }
}

运行结果:

SSClass
SuperClass init
123
123
789

代码二:

class SSClass {
    static {
        System.out.println("SSClass");
    }
}
class SuperClass extends SSClass {
    static {
        System.out.println("SuperClass init");
    }
    public static int value = 123;
    public SuperClass() {
        System.out.println("init SuperClass");
    }
}
class SubClass extends SuperClass {
    static {
        System.out.println("SubClass init");
    }
    //与代码一的区别
    static int value = 456;
    public SubClass() {
        System.out.println("init SubClass");
    }
}
public class NotInitialization {
    public static void main(String[] args) {
        System.out.println(SuperClass.value);
        System.out.println(SubClass.value);
        SubClass.value = 789;
        System.out.println(SuperClass.value);
    }
}

运行结果:

SSClass
SuperClass init
123
SubClass init
456
123

代码三:

class SSClass {
   static {
       System.out.println("SSClass");
   }
}
class SuperClass extends SSClass {
   static {
       System.out.println("SuperClass init");
   }
   public SuperClass() {
       System.out.println("init SuperClass");
   }
   public static void tryPrint() {
       System.out.println("父类打印");
   }
}
class SubClass extends SuperClass {
   static {
       System.out.println("SubClass init");
   }
   public SubClass() {
       System.out.println("init SubClass");
   }
   public static void tryPrint(String str) {
       System.out.println("打印: " + str);
   }
}
public class NotInitialization {
   public static void main(String[] args) {
       SubClass.tryPrint();
       SubClass.tryPrint("字符串");
   }
}

运行结果:

SSClass
SuperClass init
父类打印
SubClass init
打印: 字符串

对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类引用父类中定义的静态字段,只会出发父类初始化而不会触发子类初始化。然而如果父类中定义了相同名字的静态变量或方法,则与父类中原有的静态变量已经不是同一个变量或方法。也就是说对于静态变量和方法,是要被类直接调用的,没有重写这一说

static的一个重要用途是实现单例模式,即该类只能有一个实例。为了实现这一功能,必须隐藏类的构造函数,将其声明为private,并提供一个对象和获取对象的方法,都声明为static。
示例:

//在类初始化时,已经自行实例化   
public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    }  
}

静态代码块注意只会被执行一次。
静态内部类见内部类详解

  1. final关键字
    在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。
    1、修饰类: 当用final修饰一个类时,表明这个类是最终类,不能被继承。如果一个类你不想让它被继承,就可以用final进行修饰。
    2、修饰方法:使用final修饰的方法不能被子类重写,可以重载。(最终方法)
    3、修饰变量: 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。注意,final的不可变性指的是引用不可变,即它只能指向初始时的那个对象,而不关心指向的对象内容的变化。
    由final修饰的变量,是常量,一旦初始化后,它的值不能被修改,即不能被重新赋值,主要是项目中应用的常量的抽取:比如URL常量、路径常量、数字常量等.不能让人轻易修改。
    注意: 当final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。

总之,static强调被类直接调用,早于对象且与特定对象无关。final强调不可更改性。