zoukankan      html  css  js  c++  java
  • 类字面常量

    Java还提供了另一种方法来生成对Class对象的引用,即使用类字面常量。
    这样做不仅更简单,而且更安全,因为它在编译时就会受到检查(因此不需要置于try语句块中),并且它根除了对forName方法的引用,所以也更高效。类字面常量不仅可以应用于普通的类,也可以应用于接口、数组以及基本数据类型。

    当使用“.class”来创建对Class对象的引用时,不会自动地初始化该Class对象,初始化被延迟到了对静态方法(构造器隐式的是静态的)或者非final静态域(注意final静态域不会触发初始化操作)进行首次引用时才执行。而使用Class.forName时会自动的初始化。

    为了使用类而做的准备工作实际包含三个步骤:
    - 加载:由类加载器执行。查找字节码,并从这些字节码中创建一个Class对象
    - 链接:验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
    - 初始化:如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。

    package example;
    
    import java.util.Random;
    
    class Initable {
        static final int staticFinal = 47;
        static final int staticFinal2 = Test.rand.nextInt(1000);
    
        static {
            System.out.println("Initializing Initable");
        }
    }
    class Initable2 {
        static int staticNonFinal = 147;
    
        static {
            System.out.println("Initializing Initable2");
        }
    }
    class Initable3 {
        static int staticNonFinal = 74;
    
        static {
            System.out.println("Initializing Initable3");
        }
    }
    public class Test  {
        public static Random rand=new Random(47);
        public static void main(String[] args){
            
            Class initable = Initable.class;
            System.out.println("After creating Initable ref");
          
            System.out.println(Initable.staticFinal);
           
            System.out.println(Initable.staticFinal2);//开始初始化
    
            System.out.println(Initable2.staticNonFinal);
    
            try {
                Class initable3 = Class.forName("example.Initable3"); //立即初始化
            } catch (ClassNotFoundException e) {
                System.out.println("Can't find Initable3");
                System.exit(1);
            }
            System.out.println("After creating Initable3 ref");
            System.out.println(Initable3.staticNonFinal);
        
        
            
        }
        
    }

    输出:

    After creating Initable ref
    47
    Initializing Initable
    258
    Initializing Initable2
    147
    Initializing Initable3
    After creating Initable3 ref
    74

    可以得出:

    1.仅适用 .class语法来获得类的引用不会引发初始化,但是用Class.forname()就立即进行了初始化。

    2,如果一个Static final值是编译器常量,就像staticFinal那样,那么这个值不需要对Initable类进行初始化时就

    可以被读取,但是如果一个域设置为static和final,还不足以确保这种行为,例如,Initable.staticFinal2的访问将会

    强制进行类的初始化,因为他不是一个编译器常量。

    3如果一个域是static但不是final的,那么在对他进行访问时,总是要求他在被读取之前,要先进行链接(为这个域分配存储空间)和

    初始化(初始化该存储空间),就像对Initable2.staticNonFinal访问看到的结果

  • 相关阅读:
    PHP学习笔记(三)
    简单的学习心得:网易云课堂Android开发第六章SQLite与ContentProvider 熊,我
    简单的学习心得:网易云课堂Android开发第三章自定义控件 熊,我
    简单的学习心得:网易云课堂Android开发第五章SharedPreferences与文件管理 熊,我
    简单的学习心得:网易云课堂Android开发第四章服务、广播与酷特性 熊,我
    本地Server发布外网Web应用(Oray实现)
    玩玩微信公众号Java版之准备
    C语言的第零次作业
    C语言博客作业02循环结构
    C语言博客作业03函数
  • 原文地址:https://www.cnblogs.com/xurui1995/p/5306782.html
Copyright © 2011-2022 走看看