zoukankan      html  css  js  c++  java
  • Java RTTI和反射

    一、Java的RTTI 

           RTTI(Run-Time Type Identification,通过运行时类型识别)的含义就是在运行时识别一个对象的类型,其对应的类是Class对象,每个java里面的类都对应一个Class对象(在编写并且编译后),这个对象被保存在这个类的同名class文件里。


    类加载器在类被第一次静态调用(比如一个静态方法,一个静态代码块或者new关键字调用构造器,注意contructors其实都是静态的)时会把那个对应的Class对象加载到内存中。

    Class类有名的一个static方法是forName。Class.forName("classname with packagepath");通过这个静态方法返回的一个对类的Class对象的引用,用户可以在运行时动态得到大量关于这个类的信息,包括接口,父类,方法,静态成员,甚至是像newInstance()方法这样的一个实现“虚拟构造器”的一种方式。所谓的虚拟构造器,就是声明“我不知道你的确切类型,至少在编译期不知道,但是我就是要正确的创建你的一个对象”。

    比如说c是某个类的Class对象
    Class superc = c.getSuperClass();
    Object obj = null;
    obj = c.newInstance();
    毫无疑问,这个obj实际指向的对象是c的父类的一个对象。
    鉴于java的单继承模式,这个父类显然是唯一确定的,尽管在编译时我完全不知道它的类名。

    Java提供的另外一种更加安全的得到Class类的对象的方式是,使用类字面常量。
    classname.class;

    Java在RTTI中的第三种形式是最常见的。就是instanceof关键字,用法就不多说了。该关键字的调用其实就是使用了Class对象,并且返回一个布尔值。如果说instanceof和Class的比较唯一的不同,那就是instanceof如果是其子类的对象也会返回true,而Class对象比较的会是确切的那个类型。

    这样得到类的Class对象可以在编译器就得到检查。

    RTTI的限制?显然它在编译时必须知道一个非常重要的东西:类名(甚至是全类名)

    二、Java的反射

         Java中有时候在编译器为程序生成代码很久之后才会出现要处理的那个类,那么这个时候怎么才能处理这个类呢,即在编译的时候根本无法获知这个对象所属的类。答案就是利用Java的反射机制。Java的反射与RTTI的区别就在于编译时不需要知道任何事情,匿名对象的信息在运行时确定下来就可以。

         例如:

    [java] view plain copy
     
     print?
    1. public class ShowMethods {  
    2.     private static String usage=  
    3.             "usage"+  
    4.     "showMethods qualified.class.name "+  
    5.                     "To show all methods in class or: "+  
    6.     "showMethods qualified.class.name word "+  
    7.                     "To search for methods involving 'word'";  
    8.     private static Pattern p=Pattern.compile("\w+\.");  
    9.   
    10.     /** 
    11.      * @param args 
    12.      */  
    13.     public static void main(String[] args) {  
    14.         // TODO Auto-generated method stub  
    15.     if(args.length<1){  
    16.         System.out.println(usage);  
    17.         System.exit(0);  
    18.     }  
    19.     int lines=0;  
    20.     try{  
    21.         Class<?> c=Class.forName(args[0]);  
    22.         Method[] methods=c.getMethods();  
    23.         Constructor[] ctors=c.getConstructors();  
    24.         if(args.length==1){  
    25.             for(Method method:methods)  
    26.                 System.out.println(p.matcher(method.toString()));  
    27.             for(Constructor cotr:ctors)  
    28.                 System.out.println(p.matcher(cotr.toString()));  
    29.             lines=methods.length+ctors.length;  
    30.         }else{  
    31.             for(Method method:methods)  
    32.                 if(method.toString().indexOf(args[1])!=-1){  
    33.                 System.out.println(method.toString());  
    34.             lines++;  
    35.                 }  
    36.               }  
    37.             for(Constructor ctor:ctors)  
    38.                 if(ctor.toString().indexOf(args[1])!=-1){  
    39.                     System.out.println(p.matcher(ctor.toString()).replaceAll(""));  
    40.                     lines++;  
    41.                 }  
    42.     }catch(ClassNotFoundException e){  
    43.         System.out.println("No such class"+e);  
    44.     }  
    45.     }  

    在这个类编译时:javac ShowMethods.java  

    //这个时候完全不知道

    [java] view plain copy
     
     print?
    1. Class<?> c=Class.forName(args[0]);  

    中的args[0]的内容是什么。

    运行时:java ShowMethods ShowMethods

    此时第二个ShowMethods为参数传递进去,即运行时才获得了类型信息。这便是反射。

  • 相关阅读:
    HDU 1213 How Many Tables(并查集,简单)
    POJ 1611 The Suspects(并查集,简单)
    HDU 4539 郑厂长系列故事――排兵布阵(曼哈顿距离)
    POJ 2411 Mondriaan'sDream(状压DP)
    ZOJ 4257 MostPowerful(状压DP,简单)
    HDU 3001 Traveling(状压DP)
    POJ 3311 Hie with the Pie(Floyd+状态压缩DP)
    POJ 1185 炮兵阵地(状态压缩DP)
    POJ 3254 Corn Fields(状态压缩DP)
    XueXX and Chessboard(dp)
  • 原文地址:https://www.cnblogs.com/huajiezh/p/5826290.html
Copyright © 2011-2022 走看看