笔记:反射Reflect

  1. 概念
    java中的重要工具,提供了运行时再根据需要创建对象的功能,提供访问、检测和修改本身状态或行为的能力,也就是说可以修改声明,成员变量,方法和构造方法。
  2. 作用
    1)反编译。编译是将java文件通过javac命令生成.class类文件,反编译就是反过来。
    2)通过反射机制访问java对象的属性/字段,方法,构造方法
  3. java中相关的类
    1)java.lang.Class 类
    2)java.lang.reflect.Modifier 修饰符
    3)java.lang.reflect.Field 成员变量
    4)java.lang.reflect.Method 方法
    5)java.lang.reflect.Contructor 构造方法
  4. 实际的使用,见下方代码块(具体方法的使用在注释中有说明)
  5. 总结
    1)Class类常用方法
    forName(String ClassFullName)
    getName()
    getSimpleName()
    getModifiers()
    getField(String fieldName)
    getFields()
    getDeclaredFields()
    getMethod(methodName,parameter.Class,…)
    getMethods()
    getDeclaredMethods()
    getDeclaredConstruct(parameter.Class…)
    getDeclaredConstructs()
    getSuperclass()
    getInterfaces() Class[]
    2)Modifier类常用方法
    static toString(mod)
    3)Field类常用方法
    getModifiers()
    getType()
    getName()
    4)Method类常用方法
    getModifiers()
    getReturnType()
    getName()
    getParamterTypes() Class
package com.tests;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;

import com.classes.*;

/**
 * 反射:Java中的工具,运行时再使用。
 *     程序可以 访问,检测和修改   本身状态或行为的能力,根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关语义。
 * 作用:1.反编译  字节码文件.class->java文件 .java
 *     2.通过反射机制访问java对象的   属性/字段,方法,构造方法
 * Java中相关的类:
 *     1.java.lang.Class               类
 *     2.java.lang.reflect.Modifier    修饰符
 *     3.java.lang.reflect.Field       成员变量
 *     4.java.lang.reflect.Method      方法
 *     5.java.lang.reflect.Contructor  构造方法
 *     
 * 下面进入实际的使用方法:
 *     1.获得类的相关信息
 *       1.1 获得类的类型的三种方式
 *           1.1.1 Class c1 = Class.forName("HighStudent");
 *           1.1.2 Class c2 = HighStudent.Class;
 *           1.1.3 Student hs = new HighStudent();  Class c3 = hs.getClass()
 *       1.2 获得目标类名
 *           1.2.1 String s1 = c1.getName();          获得全名(com.classes.HighStudent)
 *           1.2.2 String s2 = c1.getSimpleName();    获得简化的名字(HighStudent)
 *       1.3 获得类的修饰词
 *           Modifier mod = c1.getModifiers();
 *           String modifiers = Modifier.toString(mod);
 *         
 *     2.获得类类型后,通过类类型实例的newInstance可以创建目标类的实例
 *       Object o = c1.newInstance();
 *       
 *     3.获得属性/字段/变量
 *       Field[] fs1 = c1.getFields();     //获得全部获得目标类的所有的公共(public)的字段,包括父类声明的。
 *       Field[] fs2 = c1.getDeclaredFields();    //获得该类所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段。
 *       Field f = c1.getDeclaredField("fieldName");   获得指定名称的属性
 *       3.1 Field的方法
 *           f.getModifiers()    获得字段的修饰词
 *           f.getType()         获得字段的类型
 *           f.getName()         获得字段的名称
 *       3.2 打破封装
 *           通过获得指定的属性,然后通过Field类型对象fn的setAccessible(boolean)方法设置可以通过set(key,value)的方法对key对象设置fn属性为value
 *           Field fn = c1.getDeclaredField("fieldName");
 *           Object object = c1.newInstance();
 *           fn.setAccessible(true);
 *           fn.set(object,"小明爸爸");
 *           //此时打印object对象的FatherName属性为“小明爸爸“
 *           String s = ((HighStudent)object).getFatherName();
 *           System.out.println(s);
 *           
 *     4.获得方法
 *       Methods[] methods = c1.getDeclaredMethods()    //自己声明的所有方法
 *       Methods[] methods = c1.getMethods()     //获得所有public的方法,包括父类的
 *       Method method = c1.getMethod(methodName,methodParamterTypes)    //获得指定名称和顺序参数列表的方法
 *       4.1 Method类型实例方法  
 *           getReturnType()       获取返回值
 *           getParamterTypes()    获取方法参数列表
 */   
public class InfoOfClasses {
    public static void main(String[] args){
        try {
            /*
             * 获得类类型的三种方法
             */
            //第1种方法,使用Class类的forName(类的全名)方法
            Class c1 = Class.forName("com.classes.HighStudent");
            //第2种方法,使用目标类的class属性
            Class c2 = HighStudent.class;
            //第3种方法,调用目标类实例的getClass()方法,这样获得的是运行时类类型
            Student hs = new HighStudent();
            Class c3 = hs.getClass();
            /*String[] ss = new String[]{c1.toString(),c2.toString(),c3.toString()};
            for (String s : ss) {
                System.out.println(s);
            }
            String[] ss = new String[]{c1.getSimpleName(),c2.getSimpleName(),c3.getName()};
            for (String s : ss) {
                System.out.println(s);
            }*/

            /*
             * 获得类类型后,通过类类型实例的newInstance可以创建目标类的实例
             */
            Object o = c1.newInstance();
            /*String s = o.toString();
            System.out.println(s);*/

            /*
             * 获得类类型后,通过类类型实例的getModifiers()得到 整型的修饰符编码,
             * 再通过Modifier的toString(int mod)
             * 方法将该修饰符编码转为String类型的修饰符名称
             */
            int ms = c1.getModifiers();
            String modName = Modifier.toString(ms);
            /*System.out.println(modName+" class "+c1.getSimpleName()+"(){");*/
            /**
             * 打印所有属性/成员变量
             */
            /*
             * 通过类类型的getFields()方法获得目标类的所有的公共(public)的字段,包括父类声明的。
             * getDeclaredFields()方法某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段。
             * getField(String fieldName),getDeclaredField(String fieldName)获得指定名称的属性/成员变量
             * Field的方法 getModifiers()获得修饰词  getType()获得类型  getName()获得属性名
             * 
             * 
             */
            Field[] fs1 = c1.getFields();
            Field[] fs2 = c1.getDeclaredFields();

            /*Field fn = c1.getDeclaredField("fatherName");
             Object object = c1.newInstance();
             fn.setAccessible(true);
             fn.set(object,"小明爸爸");
               String s = ((HighStudent) object).getFatherName();
               System.out.println(s);*/
            StringBuilder sb = new StringBuilder();
            sb.append(Modifier.toString(c1.getModifiers())+" Class "+c1.getSimpleName()+"(){\n");
            for (Field field : fs2) {
                sb.append("\t"+Modifier.toString(field.getModifiers())+" "+field.getType().getSimpleName()
                        +" "+field.getName()+";\n");
            }

            /**
             * 打印所有方法
             */
            /*
             * 获取方法: getDeclaredMethods()自己声明的所有方法   getMethods()获得所有public的方法,包括父类的
             * 获取指定方法:getMethod(methodName,methodParamterTypes)
             * Method类型实例  获取方法参数列 :Class<?> params = method.getParamterTypes(); fore{String name = param.getSimpleName;}
             */
            Method[] methods = c1.getDeclaredMethods();
            for (Method method : methods) {
                sb.append("\t"+Modifier.toString(method.getModifiers())+" "+
                   method.getReturnType().getSimpleName()+" "+method.getName()+"(");
                //获得方法的参数列的属性值数组
                Class<?>[] params = method.getParameterTypes();
                //获得参数的名字
                for (Class<?> class1 : params) {
                    String paramName = class1.getSimpleName();
                    sb.append(paramName+",");
                }
                //判断字符串最后一个字符是不是逗号
                if(sb.lastIndexOf(",")==(sb.length()-1)){
                    sb.deleteCharAt(sb.length()-1);
                }
                sb.append(");\n");
            }
            /**
             * 打印构造方法
             * 获取所有构造方法  getDeclaredConstructors();
             * 获取指定的构造方法  getDeclaredConstructor(parameterTypes);
             * Constructor类型其他方法与方法类型类似
             */
            Constructor[] constructors = c1.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                sb.append("\t"+Modifier.toString(constructor.getModifiers())+" "+constructor.getDeclaringClass().getSimpleName()+"(");
                Class<?>[] params = constructor.getParameterTypes();
                //获得参数的名字
                for (Class<?> class1 : params) {
                    String paramName = class1.getSimpleName();
                    sb.append(paramName+",");
                }
                //判断字符串最后一个字符是不是逗号
                if(sb.lastIndexOf(",")==(sb.length()-1)){
                    sb.deleteCharAt(sb.length()-1);
                }
                sb.append(");\n");
            }
            sb.append("}");
            System.out.println(sb);

            /*System.out.println(Modifier.toString(f.getModifiers())+" "+f.getType().getSimpleName()+" "+f.getName());
            */
            /**
             * 打印目标类的父类和接口
             * 获取父类 getSuperclass()
             * 获取接口 Class[] infas = c1.getInterfaces()
             */
            StringBuilder sb2 = new StringBuilder();
            sb2.append(c1.getSimpleName()+"类的父类是"+c1.getSuperclass().getSimpleName()+"\n");
            if(c1.getInterfaces().length!=0){
                sb2.append(c1.getSimpleName()+"类实现了");
                Class[] interfaces = c1.getInterfaces();
                for (Class infa : interfaces) {
                    sb2.append(infa.getSimpleName()+"、");
                }
                if(sb2.lastIndexOf("、")==(sb2.length()-1)){
                    sb2.deleteCharAt(sb2.length()-1);
                }
                sb2.append("接口");
            }
            System.out.println(sb2);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } /*catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/


    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值