zoukankan      html  css  js  c++  java
  • [Java] 类和接口的初始化步骤

    类和接口在初始化化时,处理继承层级的方法不一样。

    类继承的初始化:通过引用 static 字段,触发某个类的初始化,则声明该字段的类,以及该类的父类被初始化。

    接口继承的初始化:通过引用 static 字段,触发某个接口的初始化,则声明该字段的接口会被初始化,但该接口的父接口不会被初始化。

    想了解其他触发类初始化的方法,可参看另一篇博文 类的初始化步骤 。

    注意一点,接口字段全部隐式地被修饰为 public, static, final 。因此,所有的接口字段实际上都是 static 的,无论有没有显示地声明 static 。这点和接口无法被实例化规定是相吻合的。

    类继承的初始化例子

    Super, 父类。

    C, 继承 Super 类。

    Sub, 继承 C 类。

    InitDemo, 演示类继承的初始化。

    package execution.initializationExtends;
    public class Super {
    static String superName = "superName"; static{ System.out.println(" initializing Super "); } }
    package execution.initializationExtends;
    public class C extends Super{
        
        static String cName = "cName";
        static {
            System.out.println(" initializing C ");
        }
    }
    package execution.initializationExtends;
    public class Sub extends C{
    
        static{
            System.out.println(" initializing Sub ");
        }
    }

    InitDemo 演示类继承的初始化,通过引用类的变量,触发类被初始化。需要注意的是,在这里 cName 字段的声明类是 C 类,不是 Sub 类。

    package execution.initializationExtends; 
    public class InitDemo {
        public static void main(){
            System.out.println(Sub.cName);
        }
    }

    输出

     initializing Super 
     initializing C 
    cName

    根据初始化可见,只有 static 字段的声明类 C ,以及其父类 Super 被初始化了,输出代码中 Sub 类没有被初始化。

    接口继承的初始化例子

    Output,用于输出接口初始化的情况。由于接口内不能直接带静态代码块,所有通过 Output 类输出接口的初始化情况。

    SuperI, 接口父类;

    I, 继承 SuperI 接口;

    SubI, 继承 I 接口。

    InitIDemo,演示接口继承的初始化。

    package execution.initializationExtendsI;
    public class Output {
        
        public static String printWhenInit(String s){
            System.out.println(s);
            return s.substring(s.indexOf(" "));
        }
    }
    package execution.initializationExtendsI;
    public interface SuperI {
        public static String superField = Output.printWhenInit(" initializing SuperI.superField ");
    }
    package execution.initializationExtendsI;
    public interface I extends SuperI{
        public static String iField = Output.printWhenInit("initializing I.iField ");
    }
    package execution.initializationExtendsI;
    public interface SubI extends I {
        public static String subField = Output.printWhenInit(" initializing SubI.subField ");
    }

    和前面的类继承初始化例子相似,iField 字段的声明接口不是 SubI, 而是 I 。

    package execution.initializationExtendsI;
    public class InitIDemo {
        public static void main(){
            System.out.println(SubI.iField);
        }
    }

    输出

    initializing I.iField 
     I.iField 

    由输出可见,只有 iField 字段的声明接口 I 被初始化了。输出代码的 SubI 、父接口 SuperI 都没有被初始化。

    参考资料

    9.3 Field (Constant) Declarations, The Java Language Specification, Java SE 8 Edition

    12.4.1 When Initialization Occurs, The Java Language Specification, Java SE 8 Edition

  • 相关阅读:
    Java Math 取整的方式
    Java final 关键词修饰类、方法、变量
    Android Activity 开发常用技巧整理
    Java override 和 overload 的区别
    Android TextView 常用技巧
    Android Adb 常用命令
    Android 实现应用升级方案(暨第三方自动升级服务无法使用后的解决方案)
    Git 常用命令
    Android 常见Crash Log汇总
    Java Annotation 总结
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5599377.html
Copyright © 2011-2022 走看看