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

    运行时,识别对象和类的信息有两种方法:
         1、RTTI
         2、“反射”机制
     
    RTTI 即 Run Time Type Identification 运行时类型识别
    在java中,RTTI表现在:
      1、Class对象是RTTI的核心,每个类都有一个Class对象
      2、instanceof 关键字,用于检查对象是不是某个特定类型的实例
      3、强制类型转换
     
    RTTI示例:
     1 public class RTTITest {
     2 
     3     public static void main(String[] args) {
     4         Number n = 123L;
     5 
     6         //c1 c2 c3都是java.lang.Class类的对象
     7         Class<? extends Number> c1 = n.getClass();
    8 Class<Number> c2=Number. class; 9 Class<Long> c3=Long. class; 10 11 System. out.println(c1.getName()); 12 System. out.println(c2.getName()); 13 System. out.println(c3.getName()); 14 15 //== 和 equals()是等价的 16 System. out.println((c1==c2)+" " +(c1.equals(c2))); 17 System. out.println(c1.equals(c3)); 18 19 //instanceof 关键字和Class.isInstance等价的 20 //指“你是这个类吗?或者 你是这个类的派生类吗?” 21 System. out.println(n instanceof Number); 22 System. out.println(Number.class.isInstance(n)); 23 System. out.println(n instanceof Long); 24 System. out.println(Long.class.isInstance(n)); 25 } 26 }
    输出:
    java.lang.Long     ---- n.getClass().返回对象n运行时的Class对象,所以是Long.class,而不是Number.class
    java.lang.Number
    java.lang.Long

    false false
    true

    true
    true
    true
    true
    Java语言的反射机制
    使java具有动态语言的特性:动态获取类的信息、动态调用类的方法
     
    Java反射机制提供一下功能:
      1、运行时判断任意一个对象所属的类
      2、运行时构造任意一个类的对象
      3、运行时判读任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法)
      4、运行时调用任意一个对象的方法
     
    Java反射机制相关的API简介(位于java.lang.reflect)
      Class类:代表一个类
      Field类:代表类的成员变量
      Method类:代表类的方法
      Constructor类:代表类的构造方法
     
     1 import java.lang.reflect.Field;
     2 import java.lang.reflect.Method;
     3 import java.lang.reflect.Modifier;
     4 
     5 
     6 class Person{
     7     private final String name;
     8     private int age = 20;
     9     private String sex;
    10 
    11     public Person(String name) {
    12         this.name = name;
    13     }
    14     public void sayHello(String name, int age) {
    15         System.out.println(name + "  " + age);
    16     }
    17 
    18     public int getAge() {
    19         return age;
    20     }
    21     public void setAge(int age) {
    22         this.age = age;
    23     }
    24     public String getSex() {
    25         return sex;
    26     }
    27     public void setSex(String sex) {
    28         this.sex = sex;
    29     }
    30     public String getName() {
    31         return name;
    32     }
    33 }
    34 
    35 public class WatchClassInfo {
    36 
    37     public static void main(String[] args) throws Exception {
    38         Person person = new Person("Shao");
    39         person.setSex("man");
    40         Class<?> c = person.getClass();//获得运行时对象的类对象
    41         Class<?> superClass=person.getClass().getSuperclass();//获得运行时对象的基类类对象
    42 
    43         System.out.println("class loader : "+c.getClassLoader());
    44         System.out.println("class name : "+c.getName());
    45         System.out.println("super class name "+superClass.getName());
    46 
    47 
    48         System.out.println("-----------查看类中声明的数据成员,及其值-----------");
    49         Field[] fields=c.getDeclaredFields();//获得类的数据成员信息
    50         for (int i = 0; i < fields.length; i++) {
    51             Field field=fields[i];
    52             System.out.print(field.getType().getSimpleName()+" "+field.getName());
    53 
    54             String fieldName=field.getName();
    55             String upper=fieldName.substring(0, 1).toUpperCase();
    56             String getName="get"+upper+fieldName.substring(1);
    57             Method getMethod=c.getMethod(getName, new Class[]{});
    58 
    59             Object fieldValue=getMethod.invoke(person,new Object[]{});//在person对象上调用getter方法
    60             System.out.println(" = "+fieldValue);
    61         }
    62 
    63 
    64         System.out.println("-----------查看类中声明的方法-------------------");
    65         Method method[] = c.getDeclaredMethods();//获得类的方法信息
    66         for (int i = 0; i < method.length; ++i) {
    67             Class<?> returnType = method[i].getReturnType();
    68             Class<?> para[] = method[i].getParameterTypes();
    69             int temp = method[i].getModifiers();
    70             System.out.print(Modifier.toString(temp) + " "+returnType.getName() + "  "+method[i].getName() + " "+"(");
    71 
    72             for (int j = 0; j < para.length; ++j) {
    73                 System.out.print(para[j].getName() + " " + "arg" + j);
    74                 if (j < para.length - 1) {
    75                     System.out.print(",");
    76                 }
    77             }
    78             System.out.println(")");
    79         }
    80     }
    81 
    82 }

    输出:
    class loader : sun.misc.Launcher$AppClassLoader@addbf1
    class name : edu.shao.typeinfo.reflect.Person
    super class name java.lang.Object
    -----------查看类中声明的数据成员,及其值-----------
    String name = Shao
    int age = 20
    String sex = man
    -----------查看类中声明的方法-------------------
    public void  setSex (java.lang.String arg0)
    public void  sayHello (java.lang.String arg0,int arg1)
    public int  getAge ()
    public void  setAge (int arg0)
    public java.lang.String  getSex ()
    public java.lang.String  getName ()

    RTTI和反射之间真正的区别在于:
      1、对于RTTI来说,编辑器在编译时打开或检查.class文件。换句话说,我们可以用“普通”方法调用对象的所有方法。
      2、对于反射机制来说,.class文件在编译时是不可获取的,所以是在运行时打开和检查.class文件。
  • 相关阅读:
    刷题[CISCN2019 华东南赛区]Web4
    刷题[GWCTF 2019]你的名字
    刷题[b01lers2020]Life on Mars
    刷题[SUCTF 2018]GetShell
    洛谷入门2-分支结构
    洛谷入门3-循环结构:回文质数、斐波那契数列
    洛谷入门3-循环结构:金币、最长连号
    洛谷入门3-循环结构:津津的储蓄计划
    C++类成员初始化方法
    英语听力
  • 原文地址:https://www.cnblogs.com/windlaughing/p/2921895.html
Copyright © 2011-2022 走看看