java自学日记6

来源:互联网 发布:linux服务器开发待遇 编辑:程序博客网 时间:2024/05/16 17:44
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

运行时类型信息(RTTI + 反射)

  • 概念
    RTTI:运行时类型信息使得你可以在程序运行时发现和使用类型信息。
  • 使用方式
    Java是如何让我们在运行时识别对象和类的信息的,主要有两种方式(还有辅助的第三种方式,见下描述):

    • 一种是“传统的”RTTI,它假定我们在编译时已经知道了所有的类型,比如Shape s = (Shape)s1;
    • 另一种是“反射”机制,它运行我们在运行时发现和使用类的信息,即使用Class.forName()
    • 其实还有第三种形式,就是关键字instanceof,它返回一个bool值,它保持了类型的概念,它指的是“你是这个类吗?或者你是这个类的派生类吗?”。而如果用==或equals比较实际的Class对象,就没有考虑继承—它或者是这个确切的类型,或者不是。
  • 工作原理
    要理解RTTI在Java中的工作原理,首先必须知道类型信息在运行时是如何表示的,这项工作是由称为Class对象的特殊对象完成的,它包含了与类有关的信息。Java送Class对象来执行其RTTI,使用类加载器的子系统实现

无论何时,只要你想在运行时使用类型信息,就必须首先获得对恰当的Class对象的引用,获取方式有三种:
(1)如果你没有持有该类型的对象,则Class.forName()就是实现此功能的便捷途,因为它不需要对象信息;
(2)如果你已经拥有了一个感兴趣的类型的对象,那就可以通过调用getClass()方法来获取Class引用了,它将返回表示该对象的实际类型的Class引用。Class包含很有有用的方法,比如:

package rtti;interface HasBatteries{}interface WaterProof{}interface Shoots{}class Toy {    Toy() {}    Toy(int i) {}}class FancyToy extends Toyimplements HasBatteries, WaterProof, Shoots {    FancyToy() {        super(1);    }}public class RTTITest {    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("rtti.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("Can't Instantiate");            System.exit(1);        } catch (IllegalAccessException e) {            System.out.println("Can't access");            System.exit(1);        }        printInfo(obj.getClass());    }}


输出:

Class name: rtti.FancyToy, is interface? [false]
Simple name: FancyToy
Canonical name: rtti.FancyToy
Class name: rtti.HasBatteries, is interface? [true]
Simple name: HasBatteries
Canonical name: rtti.HasBatteries
Class name: rtti.WaterProof, is interface? [true]
Simple name: WaterProof
Canonical name: rtti.WaterProof
Class name: rtti.Shoots, is interface? [true]
Simple name: Shoots
Canonical name: rtti.Shoots
Class name: rtti.Toy, is interface? [false]
Simple name: Toy
Canonical name: rtti.Toy

0 0
原创粉丝点击