上一篇介绍了Java反射之成员变量的反射,这次介绍成员方法的反射。

[一]Method类

Method类中封装了所有java方法的属性,包括该方法是否私有,该方法的修饰符,返回值,参数,抛的错误等等。

为了能判断是否私有,Method也继承了java.lang.reflect.AccessibleObject

下面演示如何使用反射调用String类中charAt()方法

public static void main(String[] args) throws Exception {
String str = new String("leyvan"); Class cls = Class.forName("java.lang.String");
//得到名字叫charAt的方法,charAt参数的类型是int.class
Method method = cls.getMethod("charAt", int.class);
//str.charAt(1);
System.out.println(method.invoke(str, 1));
}

结果:

e

Class类的getMethod(String methodName,Class parameterType)方法:根据参数-方法名和参数类型个数获得相应的方法。

Method类的方法invoke(Object,Object):绑定一个执行该方法的对象,并为该方法传入一个参数调用该方法。

Class类中还有getDeclaredMethod:获得所有方法,包括私有的方法。

Method调用私有方法和Field调用私有成员一样,详细请看上一篇文章。

[二] 案例:模仿main方法,给main方法传入一个数组参数

已知某个类中已存在main方法,通过反射调用该类中的main方法,并未方法传入一个String[] args。

辅助类:

package club.leyvan.muzile;

public class GeneralClass {
public void main(String [] args){
for(String str : args){
System.out.println(str);
}
}
}

测试方法:先演示一个错误

public static void main(String[] args) throws Exception {
String[] className = new String[]{"club.leyvan.muzile.GeneralClass"};
//获得该类的Class
Class cls = Class.forName(className[0]);
//创建对象
Object obj = cls.newInstance();
//获得名为main的方法
Method main = cls.getMethod("main", String[].class);
//准备参数
String[] parameters = new String[]{"muzile","leyvan","www.leyvan.club"};
//调用方法
main.invoke(obj, parameters);
}

结果:

Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments

这里错误的原因是invoke第二个参数接收的是一个Object[]数组而Parameters是一个String的数组,但是getMethod方法中的类型要和invoke方法中的类型一致,而jdk1.4和1.5中invoke方法是不同的,因为1.5引入了可变参数,当传入不是Object数组时就会自动与1.5的方法对应,从而接受一个Object可变参数,而这里把String[]看作为一个参数,且与参数不符。

修改代码后:

public static void main(String[] args) throws Exception {
String[] className = new String[]{"club.leyvan.muzile.GeneralClass"};
//获得该类的Class
Class cls = Class.forName(className[0]);
//创建对象
Object obj = cls.newInstance();
//获得名为main的方法
Method main = cls.getMethod("main", String[].class);
//准备参数
String[] parameters = new String[]{"muzile","leyvan","www.leyvan.club"};
//调用方法
//第一种修改方式:
//main.invoke(obj, new Object[]{parameters});
//第二中修改方式
main.invoke(obj, (Object)parameters);
}

结果:

muzile
leyvan
www.leyvan.club

这里可以将parameters看作一个参数包装在Object数组中,还可以将String[]强制类型转换,变成三个参数,对应1.5以后的可变长度参数。

[三] 数组与Object及其反射类型

我们看一下下面的代码:

public static void main(String[] args) throws Exception {
int[] a1 = new int[]{1,2,3};
int[][] a2 = new int[][]{{1,2},{1,3}};
String[] s = new String[]{"a","b","c"}; System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a2));
System.out.println(Arrays.asList(s));
}

结果:

[[I@100363]
[[I@14e8cee, [I@67064]
[a, b, c]

从上面我们可以发现,a1和a2都只封装了个地址,并没有把值加入到list

这是因为,基础类型数组的父类型都是Object,基础类型的数组父类型就是Object的一维数组,所以传入asList时,被基础类型的一维数组背叛定为Object,作为一位可变参数传入方法中,所以就将object封装成数组了。

下一章:Java反射之数组的反射应用

Java反射之成员方法的反射的更多相关文章

  1. Java反射之数组的反射应用

    上一篇我们说了Java反射之成员方法的反射 这一篇我们说一说数组的反射应用,数组的有长度等属性,所以也会有相应的方法获得这些属性,这里我们不一一列举哪些方法.我们来了解反射包中的一个类----Arra ...

  2. Java学习笔记54(反射详解)

    反射概念: java反射机制是在运行状态中,对于任意一个类,都能知道所有属性和方法 对于任意一个对象都能调用它的任意一个方法和属性,这种动态获取和调用的功能称为java的反射机制 实际作用: 已经完成 ...

  3. JAVA中的糕富帅技术——反射(一)

    前言 突然发现好久没写博客了,前面写的都是关于Android的东西,今天心血来潮突然有一种冲动想写一篇基于JAVA技术的博客,别问我为什么?有钱.任性! 今天就来谈谈反射机制:学过JAVA的人不一定懂 ...

  4. java基础篇3之反射

    1.反射的基础 反射的基石---->Class类 java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class 获取字节码对应的实例对象(Class类型) class ...

  5. java基础(32):类加载、反射

    1. 类加载器 1.1 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 加载 就是指将class文件读入内存,并为之创建一个C ...

  6. Java内功修炼系列一反射

    “JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制 ...

  7. java基础第12期——反射、注解

    一. 反射 反射: 将类的各个组成部分封装为其他对象. 1.1 获取class对象的方式 Class.forName("全类名"): 将字节码文件加载进内存,返回class对象 多 ...

  8. Java 反射(一)反射简介、原理和应用场景

    目录 一.动态语言和动态语言的比较 动态语言 静态语言 二.反射 简介 反射的常见使用 1. 代码编辑器 2. Spring等框架的IoC容器 3. 和注解的配合使用 原理 反射优缺点 调试查看 Cl ...

  9. Java安全第一篇 | 反射看这一篇就够了

    什么是反射? Java安全可以从反序列化漏洞说起,反序列化漏洞又可以从反射说起.反射是⼤多数语⾔⾥都必不可少的组成部分,对象可以通过反射获取他的类,类可以通过反射拿到所有⽅法(包括私有),拿到的⽅法可 ...

随机推荐

  1. django框架基础-框架介绍-长期维护

    ###############    MVC架构介绍    ################ # MVC架构 # 一个软件框架有很多的模块,每一个模块有不同的功能 # 模块与模块之间相互配合来完成软件 ...

  2. [LC] 70. Climbing Stairs

    You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...

  3. 如何单独卸载office2016中的one note

  4. 细看Java序列化机制

    概况 在程序中为了能直接以 Java 对象的形式进行保存,然后再重新得到该 Java 对象,这就需要序列化能力.序列化其实可以看成是一种机制,按照一定的格式将 Java 对象的某状态转成介质可接受的形 ...

  5. OpenCV 改变图像的对比度和亮度

    #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <ios ...

  6. git 忽略规则

    # 以'#'开始的行,被视为注释. # 忽略掉所有文件名是 foo.txt的文件. foo.txt # 忽略所有生成的 html文件, *.html # foo.html是手工维护的,所以例外. !f ...

  7. Linux启动初始化配置文件浅析

    转自:http://blog.51cto.com/19055/1144600 1)/etc/profile   登录时,会执行. 全局(公有)配置,不管是哪个用户,登录时都会读取该文件. (2)/ec ...

  8. linux下载文件到本地_把linux服务器的文件下到本地windows

    tar -cvf script.tar scriptsz script.tar 文件夹先要打包,并且要指定打包的名字. 具体:  sz/rz命令:  一般来说,linux服务器大多是通过ssh来进行远 ...

  9. python django ORM

    1.在models.py中创创建类 # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db imp ...

  10. spring参数拼装

    -- 知道轮子是怎么造的 -- 自己试着造一造轮子 ,这样才可以更好地利用轮子,轮子的缺陷和优点才能明确. spring参数拼装,需要用到set函数,参考文档: http://coderec.cn/2 ...