JAVASE-14-Java反射

Table of Contents

1:创建Class

1.1: getClass方法

1.2:Class.forName

1.3:类名.class

1.4:Class对象.getSuperclass()获取到父类

2:获取构造方法

1:.getDeclaredConstructors():获取所有的构造方法

2:getConstructors():获取共有的构造方法

3:获取特定的构造方法

4:利用构造方法反射创建对象

5:调用类的私有构造方法

3:对类中方法的操作

1:getDeclaredMethods():获取所有的方法对象,包括私有的和实现接口的,但不包括父类的;

2:getDeclaredMethod():获取指定方法

3:.getMethod():获取public的方法包括父类的和实现接口的

4:meth1.invoke():指定特定的方法

4:通过Field类,为对象设置字段值


相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有个开源框架jOOR相信很多人都用过,不过我们还是要学习反射的基础语法,这样才能自己写出优秀的框架,当然这里所讲的反射技术,是学习Android插件化技术、Hook技术等必不可少的!
 

1:创建Class

1.1: getClass方法

        String str = "Hello";
        Class aClass = str.getClass();
        System.out.println(""+aClass.getName());//java.lang.String
        User user = new User();
        Class calss2 = user.getClass();
        System.out.println(""+calss2.getName());//com.wkl.bean.User

1.2:Class.forName

     try {
            //这里也通过捕获异常,因为我们传的这个字符串可能不合法,字符串合法命名是类的命名空间和类的名称组成
            Class<?> aClass = Class.forName("java.lang.String");
            System.out.println(""+aClass.getName());//java.lang.String
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

1.3:类名.class

 Class<User> userClass = User.class;
 System.out.println(""+userClass.getName());//com.wkl.bean.User

1.4:Class对象.getSuperclass()获取到父类

   
            Class<?> aClass = Class.forName("java.lang.String");
            System.out.println(""+aClass.getName());//java.lang.String
            String name = aClass.getSuperclass().getName();
            System.out.println(""+name);//java.lang.Object

2:获取构造方法

当类中方法定义为私有的时候我们能调用?不能!当变量是私有的时候我们能获取吗?不能!但是反射可以,比如源码中有你需要用到的方法,但是那个方法是私有的,这个时候你就可以通过反射去执行这个私有方法,并且获取私有变量。

public class User {
    private String name;
    private int age;
    private String sex;

    public User(String name) {
        this.name = name;
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private User(int age) {
        this.age = age;
    }

}

1:.getDeclaredConstructors():获取所有的构造方法

        Class<User> userClass = User.class;
   
        Constructor<?>[] constructors = userClass.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
            System.out.println("构造器名称:"+constructor.getName());
            System.out.println("修饰符类型:"+constructor.getModifiers());
            Parameter[] parameters = constructor.getParameters();
            System.out.println("构造器参数:"+ JSONArray.toJSONString(parameters));
            Class<?>[] parameterTypes = constructor.getParameterTypes();
            System.out.println("构造器参数类型:"+ JSONArray.toJSONString(parameterTypes));
            System.out.println("=====================================================");
        }

2:getConstructors():获取共有的构造方法

其余的和上边一样

3:获取特定的构造方法

我们可以通过getDeclaredConstructor()方法传参获取特定参数类型的构造方法,

这里注意是getDeclaredConstructor()不是  getDeclaredConstructors() ,所以返回的是一个Class对象而不是一个Class数组。

        Class<User> userClass = User.class;

        try {
            Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);
            System.out.println(""+declaredConstructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

不传参数,默认取无参构造方法

4:利用构造方法反射创建对象

        Class<User> userClass = User.class;
        try {
            Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);
            System.out.println(""+declaredConstructor);
            User user = declaredConstructor.newInstance("123");
            System.out.println(""+user);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

结果:

5:调用类的私有构造方法

调用私有构造方法呢,和上面一样,只是我们要设置constructors.setAccessible(true);

3:对类中方法的操作

1:getDeclaredMethods():获取所有的方法对象,包括私有的和实现接口的,但不包括父类的;

        Class<User> userClass = User.class;
        Method[] declaredMethods = userClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("方法名:"+declaredMethod.getName());
            System.out.println("修饰符"+declaredMethod.getModifiers());
            System.out.println("参数类型:"+JSONArray.toJSONString(declaredMethod.getParameterTypes()));
            System.out.println("返回类型:"+declaredMethod.getReturnType());
            System.out.println("================");
        }
方法名:toString
修饰符1
参数类型:[]
返回类型:class java.lang.String
================
方法名:moth2
修饰符2
参数类型:[]
返回类型:class java.lang.String
================
方法名:moth1
修饰符1
参数类型:[]
返回类型:class java.lang.String
================

2:getDeclaredMethod():获取指定方法

第一个参数是方法名,第二个参数是参数类型

        Class<User> userClass = User.class;
        try {
            //第一个参数是方法名,第二个参数是参数类型
            Method meth1 = userClass.getDeclaredMethod("moth1",String.class);
            System.out.println(""+ JSONObject.toJSONString(meth1));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

3:.getMethod():获取public的方法包括父类的和实现接口的

 Method meth1 = userClass.getMethod("moth1",String.class);

4:meth1.invoke():指定特定的方法

invoke需要两个参数一个是类的实例,一个是方法参数。

        Class<User> userClass = User.class;
        try {
            User user = new User("aa");
            //第一个参数是方法名,第二个参数是参数类型
            Method meth1 = userClass.getDeclaredMethod("moth1",String.class);
            Object wkl = meth1.invoke(user, "wkl");
            System.out.println(""+wkl);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
wkl:moth1

 

4:通过Field类,为对象设置字段值

        Class<User> userClass = User.class;
        Field name = userClass.getDeclaredField("name");
        User user = userClass.newInstance();
        //因为属性是私有的,所以需要设置Accessible
        name.setAccessible(true);
        name.set(user,"wkl");
        System.out.println(""+user);
User{name='wkl', age=0, sex='null'}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值