java 类型信息

本章主要学习如何让我么在运行时识别对象和类的信息的.主要有两种方式:一种是传统的RTTI它假定我们在编译时已经知道了所有的类型. 另一种是反射机制它允许我们在运行时发现和使用类的信息.

一.为什么需要RTTI(Run-Time Type Information)

 1. RTTI :在运行时识别一个对象的类型

2.反射   允许在运行时发现和使用类型信息

3.传统的RTTI 在编译期通过Class文件识别类型信息,反射在运行期通过Class文件识别类型信息。

4.Java类型转换都发生在运行时期。

 

二.Class对象

        Class对象是用来创建类的所有的"常规"对象的.java使用Class对象来执行其RTTI即使你正在执行的是转型这样的操作.

  1. 每个类都有Class对象,即编译了一个新类就会产生一个该类的Class对象,并且保存在.class文件中。Class对象就是用来产生“常规”对象的。
  2. Java使用Class对象来执行RTTI。
  3. 所有类都是第一次使用时动态加载到jvm中。 动态加载就是需要时再加载不使用不加载。
  4. 只要创建了对一个类的静态成员的引用就会加载该类。new 的时候加载类说明 类的构造器虽然没写static但也是静态方法。

一旦某个类的Class对象载入内存后,他就会用来创建该类的对象。

package test;

class Candy {
static { System.out.println("Loading Candy"); }
}

class Gum {
static { System.out.println("Loading Gum"); }
}

class Cookie {
static { System.out.println("Loading Cookie"); }
}

public class SweetShop {
public static void main(String[] args) {    
 System.out.println("inside main");
 new Candy();
 System.out.println("After creating Candy");
 try {
   Class.forName("Gum");//返回的是一个Class对象的引用如果获取失败会抛出异常 ClassNotFoundException
 } catch(ClassNotFoundException e) {
   System.out.println("Couldn't find Gum");
 }
 System.out.println("After Class.forName(\"Gum\")");
 new Cookie();
 System.out.println("After creating Cookie");
}
} /* Output:
inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie
*///:~
/* 注意新版本jdk和作者的结果不一样
 * inside main
Loading Candy
After creating Candy
Couldn't find Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie
*///~
 */

 

运行时要获得一个类的信息(类型信息)可以通过一个该类的Class对象获得,使用Class.forName()就可以做到,而不必持有该类型的对象通过该对象获得。

如果有了一个实例对象可以调用getClass()方法来获得Class对象, 这个方法属于根类Object的一部分

Class包含很多有用的方法,下面是其中的一部分

  1. getName() 获得全限定类名, getCanonicalName()也是获得全限定类名。对于普通类来说,二者没什么区别,只是对于特殊的类型上有点表示差异。
  2. getSimpleName()只获得类名,没有包名。
  3. isInterface()判断是否为接口。
  4. getInterfaces() 返回一个Class对象数组,数组元素是该类实现的接口,元素顺序和实现顺序一致。
  5. getSuperclass() 返回直接基类(不是接口)的Class对象,可以用来发现对象完整的类继续结构。
  6. newInstance()创建该类实例对象并返回,但该类必须要有默认构造器,这个方法相当于一个虚拟构造器。
//: typeinfo/toys/ToyTest.java
// Testing class Class.
package test;

interface HasBatteries {}
interface Waterproof {}
interface Shoots {}

class Toy {
  // Comment out the following default constructor
  // to see NoSuchMethodError from (*1*)
  Toy() {}
  Toy(int i) {}
}

class FancyToy extends Toy
implements HasBatteries, Waterproof, Shoots {
  FancyToy() { super(1); }
}

public class ToyTest {
  static void printInfo(Class cc) {
    System.out.println("Class name: " + cc.getName() +
      " is interface? [" + cc.isInterface() + "]");
    System.out.println("Simple name: " + cc.getSimpleName());
    System.out.println("Canonical name : " + cc.getCanonicalName());
  }
  public static void main(String[] args) {
    Class c = null;
    try {
      c = Class.forName("test.FancyToy");
    } catch(ClassNotFoundException e) {
      System.out.println("Can't find FancyToy");
      System.exit(1);
    }
    printInfo(c);    
    for(Class face : c.getInterfaces())
      printInfo(face);
    Class up = c.getSuperclass();
    Object obj = null;
    try {
      // Requires default constructor:
      obj = up.newInstance();
    } catch(InstantiationException e) {
      System.out.println("Cannot instantiate");
      System.exit(1);
    } catch(IllegalAccessException e) {
      System.out.println("Cannot access");
      System.exit(1);
    }
    printInfo(obj.getClass());
  }
} /* Output:
Class name: typeinfo.toys.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : typeinfo.toys.FancyToy
Class name: typeinfo.toys.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : typeinfo.toys.HasBatteries
Class name: typeinfo.toys.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : typeinfo.toys.Waterproof
Class name: typeinfo.toys.Shoots is interface? [true]
Simple name: Shoots
Canonical name : typeinfo.toys.Shoots
Class name: typeinfo.toys.Toy is interface? [false]
Simple name: Toy
Canonical name : typeinfo.toys.Toy
*///:~

 

posted @ 2019-02-01 22:35  江期玉  阅读(313)  评论(0编辑  收藏  举报