博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java开发知识之JAVA的反射
阅读量:5061 次
发布时间:2019-06-12

本文共 6342 字,大约阅读时间需要 21 分钟。

目录

Java中的反射机制

一丶什么是反射机制

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

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

1.使用静态属性Class获取

代码:

Class cls = Person.class; //获取自描述类    String strClassName = cls.getName();获取类的包名 + 类名    输出(strClassName);

首先我们的Class类是自描述类.可以返回这个类的描述信息.

有很多方法.比如获取类名字,方法.构造等等.

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

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方法.
    代码如下
public static void main(String[] args) throws Exception {        // TODO 自动生成的方法存根        Class cls = new Person().getClass();        String clsName = cls.getName();        System.out.println(clsName);    }

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

1197364-20181023184016550-922427955.png

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

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

1197364-20181023184346337-139074611.png

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

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对构造方法提供的方法

1197364-20181023184629610-1185397074.png

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

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

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

1197364-20181023185042337-756494695.png

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

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

1197364-20181023185138140-1509541858.png

5.对内部类提供的方法

1197364-20181023185233857-1268813423.png

总结

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

四丶反射访问构造方法

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

    1.构造方法类提供的方法.

    构造方法

    1197364-20181023190136958-2089658618.png
    请注意 newInstance.我们可以利用指定参数.创建一个该类对象.在以后的安卓逆向中.可能会需要.

    2.Modifier类

    这个类则是传入类型则是调用Construct类中的getModifiers();返回构造方法的类型.传入.然后可以判断是什么属性.
    提供的方法
    1197364-20181024131553729-1076646442.png
    1197364-20181024131616853-1575515206.png
  • 四种获得构造方法方式代码

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

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

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():获得了所有公共权限的方法,进行遍历输出了.

输出结果:
1197364-20181024132251891-1739725825.png

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

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

获取公共的权限的指定构造方法,我们就需要传入类型的Class. 比如参数为 int.Class 代表一个参数.

下方调用newInstance();就是在使用这个构造.

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

private static void getAllConstruct(Class
cls) { // TODO 自动生成的方法存根 Constructor a[] = cls.getDeclaredConstructors(); for(Constructor i:a) { System.out.println(i); } }

输出结果:

1197364-20181024133536141-834655666.png

4.获取指定的构造方法

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

private static void getPrivateConstructAnNewInstance(Class
cls) throws InstantiationException, IllegalAccessException { // TODO 自动生成的方法存根 try { Constructor
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(对应参数类型的参数); 即可实现调用.
结果图:
1197364-20181024134429658-1664850642.png

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

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

我们遍历这个数组即可.

private static void getPrivateConstructAnNewInstance(Class
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(); } }

输出结果:

1197364-20181024135106417-2102491403.png

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

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

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

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

1197364-20181024140152014-694150595.png

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

使用方法: getField(String name);

private static void getPublicAllFields(Class
cls) { // TODO 自动生成的方法存根 Field f; try { f = cls.getField("pid"); System.out.println(f); } catch (Exception e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } }

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

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

private static void getPublicAllFields(Class
cls) { // TODO 自动生成的方法存根 Field a[] = cls.getDeclaredFields(); for(Field i:a) { System.out.println(i); } }

输出结果:

1197364-20181024140821155-2049326645.png

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

private static void getPublicAllFields(Class
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方法设置值.
如果设置私有,则要设置权限才可以.

private static void getPublicAllFields(Class
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(); } }

结果:

1197364-20181024141303229-1176672400.png

转载于:https://www.cnblogs.com/iBinary/p/9838420.html

你可能感兴趣的文章
查看版本信息的命令
查看>>
安装 SQLManagementStudio_x86_CHS(SQL Server Management Studio) 老提示重启的解决办法
查看>>
asp.net要验证的用户名和密码
查看>>
你的pip是时候出问题了吧
查看>>
notepad++ 快捷键
查看>>
hive 空值、NULL判断
查看>>
Django--Ajax 提交
查看>>
ASP.NET Web API 2基于令牌的身份验证
查看>>
接口测试系列:工作中所用(七:BSTestRunner.py 生成测试报告)
查看>>
用Android-X86和VirtualBox打造高性能Android开发环境
查看>>
canvas绘制五角星
查看>>
mvc5 @RenderSection("scripts", required: false) 什么意思
查看>>
查看dump oracle数据块查看
查看>>
Jmeter 指令记录
查看>>
使用mstest.exe 命令行跑test case(不安装Visual Studio 2010)
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第5节 String类_10_练习:统计输入的字符串中...
查看>>
阶段1 语言基础+高级_1-3-Java语言高级_04-集合_01 Collection集合_4_Iterator接口介绍...
查看>>
seureCRT快捷键
查看>>
大道至简第一章读后感
查看>>
在MFC中使用ShockwaveFlash插件播放swf文件(VS2008-VC++MFC)
查看>>