JAVA核心--反射之Method.invoke()

标签: invoke() java 反射
6人阅读 评论(0) 收藏 举报
分类:

invoke

public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException

对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
参数:
obj - 从中调用底层方法的对象
args - 用于方法调用的参数
返回:
使用参数 args 在 obj 上指派该对象所表示方法的结果
抛出:
IllegalAccessException - 如果此 Method 对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。
IllegalArgumentException - 如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。
InvocationTargetException - 如果底层方法抛出异常。
NullPointerException - 如果指定对象为 null,且该方法是一个实例方法。
ExceptionInInitializerError - 如果由此方法引起的初始化失败。

如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。

如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。

如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。

如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。

既然是讲invoke方法,那就不讲怎么使用反射了,请看例子:

package com.chenjie.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class TestInvoke {
    
    public void test(String[] arg){
        for (String string : arg) {
            System.out.println(string);
        }
    }
    @Test
    public void demo1() throws Exception {
        //获取字节码对象
        Class<TestInvoke> clazz = (Class<TestInvoke>) Class.forName("com.chenjie.core.TestInvoke");
        //获取一个对象
        Constructor con =  clazz.getConstructor();
        TestInvoke m = (TestInvoke) con.newInstance();
        String[] s = new String[]{"aa","bb"};
        //获取Method对象
        Method method = clazz.getMethod("test", String[].class);
        //调用invoke方法来调用
        method.invoke(m, s);
    }
}

测试会报错:


红色框框显示是参数错误,test方法需要是字符串数组啊,我传递也是字符串数组,怎么就不对了??

让我们来看一下invoke方法:


invoke方法的参数,一个是Object类型,也就是调用该方法的对象,

第二个参数是一个可变参数类型,这个可变参数类型怎么能传递给一个数组类型呢?一个是多个参数。一个是一个数组参数,显然参数的个数不匹配,怎么解决呢?

解决办法就是将可变参数变成一个参数:

  1. 将传递进去的s强转为Object类型
  2. 将s重新包装成一个Object数组

测试一下:

package com.chenjie.core;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class TestInvoke {
    
    public void test(String[] arg){
        for (String string : arg) {
            System.out.println(string);
        }
    }
    @Test
    public void demo1() throws Exception {
        //获取字节码对象
        Class<TestInvoke> clazz = (Class<TestInvoke>) Class.forName("com.chenjie.core.TestInvoke");
        //获取一个对象
        Constructor con =  clazz.getConstructor();
        TestInvoke m = (TestInvoke) con.newInstance();
        String[] s = new String[]{"aa","bb"};
        //获取Method对象
        Method method = clazz.getMethod("test", String[].class);
        //调用invoke方法来调用
        
        //1.将传递进去的s强转为Object类型 
        method.invoke(m, (Object)s);
        //2.将s重新包装成一个Object数组
        method.invoke(m, new Object[]{s});   
    }
}

测试结果:


结果可行

查看评论

Java反射机制及Method.invoke详解

这篇文章主要介绍了Java反射机制及Method.invoke详解,本文讲解了JAVA反射机制、得到某个对象的属性、得到某个类的静态属性、执行某对象的方法、执行某个类的静态方法等内容,需要的朋友可以参...
  • coc_k
  • coc_k
  • 2016-08-01 11:38:28
  • 703

java中的反射--method的invoke方法

在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一样,去调用父类的对象也会报错,虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java...
  • freeideas
  • freeideas
  • 2015-02-05 16:43:42
  • 965

Java反射机制详解 及 Method.invoke解释

JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称...
  • Mr_Tim
  • Mr_Tim
  • 2016-06-06 12:53:11
  • 23677

反射 method的调用 无参和多参数

package test.ClassLoader; import java.lang.reflect.InvocationTargetException; import java.lang.refl...
  • AlbertFly
  • AlbertFly
  • 2016-08-25 17:17:16
  • 5448

java反射机制学习笔记与Method类invoke方法jvm底层优化方案

LZ今天面试被问到了,然后百度了一下,百度给的解释如下: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动...
  • u012235132
  • u012235132
  • 2015-05-13 20:21:10
  • 1828

java反射Method中的如何调用任意方法,即invoke()的使用

今天碰到了一个关于java反射中的Method中invoke(Object,Object...args);的使用问题,这就涉及到了反射中如何去利用这个方法去调用一个类中任意方法的问题,包括类中的静态和...
  • qi7210577
  • qi7210577
  • 2016-11-03 18:23:08
  • 196

Java中的@interface以及method.invoke()

前言  这几天在看暑假要去实习的公司的框架源码,该框架十分轻量级,上手贼快。   Web容器是Jetty,数据库是MySQL,使用该框架形式为插件开发,只需要按照该框架可以识别的规则开发,再将项目放...
  • Alone_Rojer
  • Alone_Rojer
  • 2017-04-28 22:56:11
  • 534

核心java系统——反射机制

反射的简介反射是java中一种很强大的工具,能够动态分析java的类的能力,在运行状态中,对于任意一个类,通过反射都能知道这个类的属性和方法。这种动态获取的信息以及动态调用对象的方法的功能称为Java...
  • xhwwc110
  • xhwwc110
  • 2015-11-10 21:56:41
  • 728

Java反射的效率测试-优先使用FastMethod

通过下面的测试,建议发射使用: FastMethod public class TestMethod { private static final int INT = 1; private st...
  • jiangtao_st
  • jiangtao_st
  • 2014-02-19 18:02:28
  • 2332

c#-Invoke反射简单举例

c#-Invoke反射简单举例 一个最简单的C#反射实例,首先编写类库如下: namespace ReflectionTest {  public class WriteTest ...
  • zhangbp
  • zhangbp
  • 2012-11-13 21:42:45
  • 11463
    个人资料
    持之以恒
    等级:
    访问量: 787
    积分: 577
    排名: 9万+
    文章存档