Java中static和final关键字

  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;  
        }  
    }  

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

  2. final关键字
    在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。

    1、修饰类: 当用final修饰一个类时,表明这个类是最终类,不能被继承。如果一个类你不想让它被继承,就可以用final进行修饰。

    2、修饰方法:使用final修饰的方法不能被子类重写,可以重载。(最终方法)

    3、修饰变量: 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。注意,final的不可变性指的是引用不可变,即它只能指向初始时的那个对象,而不关心指向的对象内容的变化。

    由final修饰的变量,是常量,一旦初始化后,它的值不能被修改,即不能被重新赋值,主要是项目中应用的常量的抽取:比如URL常量、路径常量、数字常量等.不能让人轻易修改。

    注意: 当final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。

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

猜你喜欢

转载自blog.csdn.net/wayne566/article/details/80206818