反射基础,没有理论,只有使用

public class DemoClass {
    private String nickName;
    public  int num = 3;
    public int add(int a,int b){
        return a + b;
    }
    public int sub(int a,int b){
        return a - b;
    }
    static {
        System.out.println("DemoClass静态代码块");
    }
    {
        System.out.println("DemoClass动态代码块");
    }
    public DemoClass(){}
    public DemoClass(String string){
        System.out.println("DemoClass构造方法");
    }
    public String getNickName() {
        return nickName;
    }
    public void setNickName(String name) {
        this.nickName = name;
    }
    public int getNum() {
        return num;
    }
    private void  testMethod(){
        System.out.println("静态方法");
    }

  1. 获取类对象

    1. 直接调用某一个类的class属性(不知道这样说合适不合适)
    2. 调用某一个对象的getClass方法
    3. 调用Class类的静态方法forName
    public class ReflectDemo {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> classDemo = DemoClass.class;//class demo.DemoClass//不会调用任何方法
            Class<?> classNew = new DemoClass().getClass();//class demo.DemoClass 静态代码块和动态代码块还有构造方法都会执行
            Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块
            System.out.println(forName);//class demo.DemoClass
            System.out.println(classDemo == classNew);//true
            System.out.println(classNew == forName);//true
            System.out.println(forName == classDemo);//true
        }
    }
    
  2. 获取类实例

    1. 通过newInstance,这种是调用单独无参构造函数,所以如果没有无参构造函数就会异常
    2. 获取指定的构造函数,再通过指定的构造函数的newInstance创建实例
    public class ReflectDemo {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> forName = Class.forName("demo.DemoClass");
            try {
                Object o = forName.newInstance();//这种每次获取的都是同一个对象,class必须有无参构造函数,否则会报错
                System.out.println(o);//demo.ReflectDemo@14ae5a
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
            try {
                Constructor<?> constructor = forName.getConstructor(String.class);
                Object parade = constructor.newInstance("parade");
                Object year = constructor.newInstance("year");
                System.out.println(parade);//demo.DemoClass@7f31245a
                System.out.println(year);//demo.DemoClass@6d6f6e28
            } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    
  3. 获取属性

    1. getFields->不能获取私有属性

    2. getDeclaredFields->可以获取私有属性

      public static void main(String[] args) throws ClassNotFoundException {
          Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块
         
          try {
              Field name = forName.getField("name");//name是私有,则会抛异常
          } catch (NoSuchFieldException e) {
              e.printStackTrace();
          }
          Field[] fields = forName.getFields();//获取所有非私有属性
          for (Field field : fields) {
              System.out.println(field.getName());
          }
          
          try {
              Field name = forName.getDeclaredField("name");
              System.out.println(name);
          } catch (NoSuchFieldException e) {
              e.printStackTrace();
          }
          Field[] declaredFields = forName.getDeclaredFields();//获取所有属性
          for (Field declaredField : declaredFields) {
              System.out.println(declaredField.getName());
          }
      }
      
    3. 属性赋值

      public static void main(String[] args) throws ClassNotFoundException {
          Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块
          try {
              Field name = forName.getDeclaredField("nickName");
              DemoClass o = (DemoClass) forName.newInstance();//通过Class对象得到实例对象
              name.setAccessible(true);//将私有属性设置为可访问
              name.set(o,"parade");//给私有属性赋值
              System.out.println(o.getNickName());//验证赋值成功
              Field num = forName.getField("num");//非私有属性赋值
      		num.setInt(o,5);
      		System.out.println(o.getNum());//验证赋值成功
      		Object o1 = num.get(o);//或者继续通过反射获取属性值
            System.out.println(o1);
          } catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) {
              e.printStackTrace();
          }
         
      }
      
  4. 获取方法->类似获取属性

    1. getMethod->不能获取私有方法

    2. getDeclaredMethods

      Method[] methods = forName.getMethods();//会得到所有非private方法,包括父类的方法
      for (Method method : methods) {
          System.out.println(method.getName());
      }
      Method[] declaredMethods = forName.getDeclaredMethods();//获取本类的所有方法,不包括父类
      for (Method declaredMethod : declaredMethods) {
          System.out.println(declaredMethod.getName());
      }
      
    3. 调用方法

      public static void main(String[] args) throws ClassNotFoundException {
          Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只会调用静态代码块
          try {
              DemoClass demoClass = (DemoClass) forName.newInstance();//调用方法前先要获得一个实例对象才能调用实例对象的方法
              Method setNickName = forName.getMethod("setNickName", String.class);
              Method getNickName = forName.getMethod("getNickName");
              setNickName.invoke(demoClass, "Are you ok");
              System.out.println(getNickName.invoke(demoClass));
              Method testMethod = forName.getDeclaredMethod("testMethod");
              testMethod.setAccessible(true);//调用私有方法同样要设置可访问
              testMethod.invoke(demoClass);
          } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
              e.printStackTrace();
          }
      }
      
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值