前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java开发知识之JAVA的反射

Java开发知识之JAVA的反射

作者头像
IBinary
发布2019-05-25 16:15:29
4990
发布2019-05-25 16:15:29
举报
文章被收录于专栏:逆向技术逆向技术

目录

  • Java中的反射机制
    • 一丶什么是反射机制
    • 二丶Class类,自描述类.获取类名的三种方法
      • 1.使用静态属性Class获取
      • 2.使用Class方法 forName()获取自描述Class
      • 3.使用Object自带的getClass返回自描述Class
    • 三丶了解一下自描述类Class方法.
      • 1.Class针对包,类,父类.接口的方法
      • 2.Class对构造方法提供的方法
      • 3.Class对方法提供的方法.
      • 4.Class对成员变量提供的方法
      • 5.对内部类提供的方法
    • 四丶反射访问构造方法
      • 2.获取公共权限指定的构造方法
      • 3.获取所权限的构造方法,放到数组中
      • 4.获取指定的构造方法
      • 5.获取构造方法所有参数类型
    • 五丶成员变量的获取以及使用
      • 1.获取所有公共权限成员变量
      • 2.获取公共权限指定的成员变量
      • 3.获取所有权限的成员变量
      • 4.获得指定权限的成员变量
      • 5.设置跟使用成员变量

Java中的反射机制

一丶什么是反射机制

  • 反射就是指Java在运行期间,可以获得类的一些信息.比如构造方法(私有共有...)以及属性

二丶Class类,自描述类.获取类名的三种方法

1.使用静态属性Class获取

代码:

代码语言:javascript
复制
    Class cls = Person.class; //获取自描述类
    String strClassName = cls.getName();获取类的包名 + 类名
    输出(strClassName);

首先我们的Class类是自描述类.可以返回这个类的描述信息. 有很多方法.比如获取类名字,方法.构造等等.

2.使用Class方法 forName()获取自描述Class

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
        // TODO 自动生成的方法存根
        Class cls = Class.forName("com.ibinary_01.Person");//传入完整类名获取Class
        String clsName = cls.getName();
        System.out.println(clsName);
}

可以看到,我们使用forName必须传入完整的类名.

3.使用Object自带的getClass返回自描述Class

  • 因为我们的类,继承了Object,所以需要实例,进行调用getClass方法. 代码如下
代码语言:javascript
复制
public static void main(String[] args) throws Exception {
        // TODO 自动生成的方法存根
        Class cls = new Person().getClass();
        String clsName = cls.getName();
        System.out.println(clsName);
    }

三个的输出结果都一样,演示一下

三丶了解一下自描述类Class方法.

1.Class针对包,类,父类.接口的方法

通过以上图片可以看到. 我们可以获得包的路径. 我们上面使用的getName(); 那么我们还可以使用getSuperclss(); 获得父类自描述类(Class),然后继续调用getName();获取父类的名称. 代码例子如下:

代码语言:javascript
复制
    public static void main(String[] args) throws Exception {
        // TODO 自动生成的方法存根
        Class cls = new Person().getClass();
        Class supercls = cls.getSuperclass();
        System.out.println(supercls.getName());
    }

当然,我使用的是getClass();首先获得自己的Class,然后在获取父类的Class,最后调用父类的Class的getName();获得类名. 我们也可以使用上面所说的三种方法.

2.Class对构造方法提供的方法

可以看到,以上是我们Class为构造方法提供的方法获取.

3.Class对方法提供的方法.

上面标题有点绕,反正就是对我们的类的方法.提供方法去操作.或者获取.

4.Class对成员变量提供的方法

一样的,对我们的成员变量也提供了方法操作.

5.对内部类提供的方法

总结
  1. 针对我们的类,方法.构造.以及成员方法都提供了方法支持.首先要熟悉类的操作.
  2. 在通过getFilds()和getMethods()方法一次获得权限为public的成员变量和方法的时候.将包含从父类中继承到的成员变量和方法.也就是说会获得父类的公共方法和成员变量
  3. getDeclaredFields()和GETdeclaredMethods();只是获得奔雷中定义的所有成员变量和方法.

四丶反射访问构造方法

  • 方面我们讲了,Class中提供了对构造方法的支持.返回Constructior这个类.
  • 这个类也提供了对构造方法的操作. 1.构造方法类提供的方法. 构造方法

请注意 newInstance.我们可以利用指定参数.创建一个该类对象.在以后的安卓逆向中.可能会需要. 2.Modifier类 这个类则是传入类型则是调用Construct类中的getModifiers();返回构造方法的类型.传入.然后可以判断是什么属性. 提供的方法

  • 四种获得构造方法方式代码 四种获得构造方法,其实是Class类提供的方法.在我们一开始已经截图给出了. 具体就是代码例子使用了.

1.获取所有公共权限的构造方法

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
        // TODO 自动生成的方法存根
        getAllConstruct(Person.class);
        
    }
    static void getAllConstruct(Class<?> cls) {
        //第一种,获得所有的构造方法
        Constructor c[] = cls.getConstructors();
        //遍历输出
        for(Constructor i:c) {
            System.out.println(i);
        }
        
    }

可以看到,上边调用的就是getConstructors():获得了所有公共权限的方法,进行遍历输出了. 输出结果:

2.获取公共权限指定的构造方法

代码语言:javascript
复制
private static void getPublicConstruct(Class<Person> cls) {
        // TODO 自动生成的方法存根
        try {
            Constructor<Person> c = cls.getConstructor(String.class,int.class);//获取指定公共权限的Construct
            c.newInstance("1",2);    //创建构造方法,并且调用
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

获取公共的权限的指定构造方法,我们就需要传入类型的Class. 比如参数为 int.Class 代表一个参数. 下方调用newInstance();就是在使用这个构造.

3.获取所权限的构造方法,放到数组中

代码语言:javascript
复制
    private static void getAllConstruct(Class<Person> cls) {
        // TODO 自动生成的方法存根
        Constructor a[] = cls.getDeclaredConstructors();
        for(Constructor i:a) {
            System.out.println(i);
        }
    }

输出结果:

4.获取指定的构造方法

获得指定的就跟上面一样.比如这次我们获得priate权限的方法.并且调用它.

代码语言:javascript
复制
    private static void getPrivateConstructAnNewInstance(Class<Person> cls) throws InstantiationException, IllegalAccessException {
        // TODO 自动生成的方法存根
        
        try {
            Constructor<Person> a = cls.getDeclaredConstructor(int.class,int.class,int.class);//获得指定的
            a.setAccessible(true);
            a.newInstance(1,1,1);
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } 
        
    }

首先我们要使用 getDeclaredConstructor(int.Class...);获取指定的构造方法 因为是私有的,所以我们要使用构造方法类提供的 setAccessible(true);设置为共有的. 此时我们在使用newInstance(对应参数类型的参数); 即可实现调用. 结果图:

5.获取构造方法所有参数类型

其实这个方法上面也提供了.叫做 getParameterTypes();这个方法返回一个Class数组. 我们遍历这个数组即可.

代码语言:javascript
复制
private static void getPrivateConstructAnNewInstance(Class<Person> cls) throws InstantiationException, IllegalAccessException {
        // TODO 自动生成的方法存根
        
        try {
            Constructor<?>[] a = cls.getConstructors();
            for(Constructor i:a) {
                System.out.println("构造函数 = " + i);//输出构造函数
                Class Par[] = i.getParameterTypes();
                for(Class j:Par) {
                    System.out.print("                      "  + j);//输出参数类型
                }
                System.out.println();
            }
            
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } 
        
    }

输出结果:

五丶成员变量的获取以及使用

1.获取所有公共权限成员变量

代码语言:javascript
复制
private static void getPublicAllFields(Class<Person> cls) {
        // TODO 自动生成的方法存根
        Field[] f = cls.getFields();//获取所有成员变量
        for(Field i:f) {
            System.out.println(i);
        }
    }

使用方法getFields()即可.输出之后会显示所有的名字.

2.获取公共权限指定的成员变量

使用方法: getField(String name);

代码语言:javascript
复制
    private static void getPublicAllFields(Class<Person> cls) {
        // TODO 自动生成的方法存根
        Field f;
        try {
            f = cls.getField("pid");
            System.out.println(f);
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } 
    }

结果同上,我们需要传入名字才可以.

3.获取所有权限的成员变量

代码语言:javascript
复制
private static void getPublicAllFields(Class<Person> cls) {
        // TODO 自动生成的方法存根
        Field a[] = cls.getDeclaredFields();
        for(Field i:a) {
            System.out.println(i);
        }
    }

输出结果:

4.获得指定权限的成员变量

代码语言:javascript
复制
    private static void getPublicAllFields(Class<Person> cls) {
        // TODO 自动生成的方法存根
        try {
            Field a = cls.getDeclaredField("name");
            System.out.println(a);
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } 
    }

5.设置跟使用成员变量

我们上面可以获取.但是我们要使用.或者要更改值. 二个步骤. 1.获取Cls new出来的实例对象. 2.使用Set方法设置值. 如果设置私有,则要设置权限才可以.

代码语言:javascript
复制
private static void getPublicAllFields(Class<Person> cls) throws Exception {
        // TODO 自动生成的方法存根
        Object obj = cls.newInstance();
        try {
            Field a = cls.getDeclaredField("name");
            a.setAccessible(true); //使用私有就要设置权限.
            a.set(obj, "张三");
            System.out.println(a.get(obj));//并且获取设置的成员变量值.
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } 
    }

结果:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-10-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java中的反射机制
    • 一丶什么是反射机制
      • 二丶Class类,自描述类.获取类名的三种方法
        • 1.使用静态属性Class获取
        • 2.使用Class方法 forName()获取自描述Class
        • 3.使用Object自带的getClass返回自描述Class
      • 三丶了解一下自描述类Class方法.
        • 1.Class针对包,类,父类.接口的方法
        • 2.Class对构造方法提供的方法
        • 3.Class对方法提供的方法.
        • 4.Class对成员变量提供的方法
        • 5.对内部类提供的方法
      • 四丶反射访问构造方法
        • 2.获取公共权限指定的构造方法
        • 3.获取所权限的构造方法,放到数组中
        • 4.获取指定的构造方法
        • 5.获取构造方法所有参数类型
      • 五丶成员变量的获取以及使用
        • 1.获取所有公共权限成员变量
        • 2.获取公共权限指定的成员变量
        • 3.获取所有权限的成员变量
        • 4.获得指定权限的成员变量
        • 5.设置跟使用成员变量
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档