理解Java的类型信息

来源:互联网 发布:2016民营经济数据 编辑:程序博客网 时间:2024/05/23 18:54

Java的类型信息

  • 理解RTTI(运行时类型信息)

    RTTI原本是C++里面的名词,在Java的官方文档中好像没有出现过这个名词,其在java界为人熟知主要还是因为B大 的《Thinking In Java》吧,毕竟在java界如同圣经般的存在。

    那么其具体是什么意思呢?其主要应用还是java的多多态与反射机制。举个栗子:

    public  class Animal extends Object{public void eat(){    System.out.println("什么都吃");}}public class Dog extends Animal {@Overridepublic void eat() {    // TODO Auto-generated method stub    System.out.println("吃骨头");}}public static void main(String[] args) throws ClassNotFoundException {    Animal a=new Dog();        a.eat();}//这里通过一个Animal的引用指向Dog对象,调用a的eat的时候实际调用的是dog的方法,底层实现就是通过RTTI找到的真实的对象

    当有一个指向基础型别(父类)的reference(引用)时,RTTI机制让你找出其所指的确切型别,由于Dog是在运行期才创建的,RTTI就是帮助我们在运行期正确判断对象类型。从而运行正确的方法。

  • RTTI的使用形式

    1. 传统的类型转换,通过RTTI保证类型转化的正确性。如果转化错误,会抛出异常。
    2. 通过Class对象查询运行时所需信息时。
    3. 使用instancef查看某个对象是否是某个类的实例的时候。
  • Class对象

    Class算是Java中一个非常特别的类了,普通的类可以描述为对象的实例的集合,那么Class类可以描述为普通的类的描述信息实例的集合。

    每一个类类都有一个Class对象,其被保存在编译后产生的.class文件中,通过JVM的类加载器生成这个对象。所有类都是在第一次使用时,才动态加载到JVM中的(当程序创建第一个对类的静态引用就会加载这个类,其实构造方法也是静态方法,虽然其前面并没有static关键字。)

    当需要使用某个类时,编译器先会判断该类是否已经加载,如果没有,先会根据类名查找.class文件,加载到内存中。

    Class<?> clazz = Class.forName("com.forever.rtti.Dog");

    通过Class的静态方法可以获得clazz对象,这里的clazz保存了Dog类的信息,包括其实现的接口以及父类的类信息,其成员属性与方法的信息。并且在获取对象信息的时候,类加载器会将该类加载到内存中。

    除了使用上面的方法外,我们还可以使用其他的方法获取Class对象

    //方法2(使用该方法时,JVM是不会加载Dog类到内存的)Class<?> clazz = Dog.class;//方法3Dog dog=new Dog();Class<?> clazz = dog.getClass();
  • 加载类的过程

    1. 加载:通过类加载器,通过查找字节码文件(.class获取网络获取),从字节码文件中创建Class对象。

    2. 链接:验证类中的字节码,为静态域分配空间,必要时会解析创建这个类所需要的对其他类的引用。

    3. 初始化:执行静态初始化器和静态初始化块。

      public class Dog extends Animal {public static final int i=0;public static int j=2;static {    System.out.println("dog init");}}public static void main(String[] args) throws ClassNotFoundException {    System.out.println(Dog.i);    System.out.println(Dog.j);}//打印结果0dog init2

      说明在对 public static final int i=0(编译期常量)访问时是不会初始化类的。

      对非编译期常量访问时会初始化类。

0 0