继续,接着上两篇博客继续往下讲反射。
八、通过反射调用类中的方法
我们还是用我们的ClassTest 这个类做操作。
我们呢,现在能通过反射获取到方法、能获取到属性。我们现在通过反射来调用一下say方法。不是以前我们通过对象去调用。而是反射。
从这里开始看起,我们现在已经获取到了Class类,
然后我们进行一下实例化,并且给两个参数
实例化之后,我们赋值给一个Object。
然后我们调用一下say方法。
我们发现并没有say方法。原因这是Object类,say方法是我们定义在了包子这个内部类中的。通过Object肯定调用不到。
那我们怎么办呢?我们这么来操做。
固定套路啊,记住即可。
先用object .getClass(),然后,在调用.getMethod(),这时候可以填写参数,我们来看一下这个getMethod()方法的源码
第一个name参数,是指的是你要调用的方法名称,比如说我们要调用say() 这个方法,那么我们给name传参传的是say即可。
第二个参数,大家可能没有见过,这个是指的我们要调用的方法的参数个数。可能说到这里大家有点蒙。我们直接举例说明
假设我们现在有两个方法,一个是方法A,需要传入三个参数,都是int类型的,然后有个方法B,需要传入4个参数,前三个都是String,最后一个是boolean。
A(int a, int b, int c){...}
B(String a, String b, String c, boolean d) {...}
如果这时候有人通过反射调用了getMethod,我们该怎么传入参数呢?
固定套路:如果反射调用A 那么就是 xxx . getClass() . getMethod("A", Integer.class, Integer.class, Integer.class);(这里需要传入包装类)
如果是反射调用B,那么就是 xxx . getClass() . getMethod("B", String.class, String.class, String.class, Boolean.class);
(ps: Class<?>... parameterTypes 这个东西我们在博客最下面说,还有如何给参数的问题也是放下面说)
知道了怎么调用,就好办了。因为我们say方法是没有参数的,所以我们啥也不给他传
object.getClass().getMethod("say"); 直接这样就行
然后这个会给我们返回一个Method,我们有了这个方法之后,我们可以使用Method这个类给我们提供的invoke方法进行调用。
这里也得需要传入一个参数,我们看一下源码需要传入什么参数
很好,都是我认识的单词,但是组成句子我就不知道是什么意思了。Google翻译一下
这也就是说,谁调用的,你放谁就好。
那很明显,我们是Object这个东西调用的,我们就把它放进去。完整的代码如下:
完美运行。
九、Class<?>... parameterTypes
我们来看一下这个是什么参数。
我们看这个费劲,我们就弄个简单的例子:
我们看一下输出什么
输出了这么个玩意,我们呢,来使用一下debug断点来进行看一下(Debug后面我会讲如何去使用,先跟我学着用一下)
鼠标移动到箭头位置,双击,就会出现这么一个小点点,这样我们就是打上断点了
我平时运行程序都会点击类似于播放的内个按钮,这次我们不要点这个,我们选择旁边和虫子一样的内个,点击运行。
点击switch,然后界面就会变成这样
这样就进入了debug模式,我们把鼠标移动到abc上,
很明显啊,这是一个数组,也就是说,String... abc居然是个数组。然后我们按F8。
知道了这是个数组,我们就需要些一个循环去遍历获取值。
但是如何添加值呢?我们总不能就添加一个asdfa这么个东西吧。其实,直接填写即可。
这个按照理想情况可以无限添加,但是,你要是添加的太多了,挤爆内存了,那就GG了。
这个String... 叫做可变参数,就是随着你给的参数数量自己改变,这里不止是可以String 还可以给别的,大家可以自己试一试。
十、如何给参数的问题
我们继续来说主题,刚刚又跑偏了
我们先来改造一下我们的包子类。我们这次随便写一个方法,给定参数,给定返回值。
顺便用一下刚刚学习的。我们来调用一下这个方法
因为我们要传入的是一个数组,所以我们这么去写getMethod
object.getClass().getMethod("getSome", int[].class);
是的,没有错,就这么搞
然后我们创建一个数组a,int[] a = {1,2,3,4,5};
最后我们调用一下使用Method的invoke方法,但是这次我们需要将参数a传过去,怎么传呢?
我们直接放进去,然后传入参数
运行一下
但是还没有完,我们最后返回了一个参数OK,这个怎么获取?
其实看method的invoke源码你会看到,他会返回一个Object,这个就是我们调用的方法所返回的参数,我们用一个Object接收一下,然后输出
感谢大家支持,记得点个关注,老司机带你上高速。