精华内容
下载资源
问答
  • java反射method.invoke
    万次阅读 多人点赞
    2018-12-26 18:00:51

    博客引用处(以下内容在原有博客基础上进行补充或更改,谢谢这些大牛的博客指导):
    Java中Method.invoke方法,反射?

    正常来说,我们调用对象的方法是通过dot运算符来进行的,这里我们介绍另一种方法,有以下几个步骤:1,获取该类的Class Type;2,通过getMethod方法获取Method对象;3,通过调用invoke方法来执行对象的某个方法;这里要特别注意下getMethod方法和invoke方法的参数,见下面的例子:

    package reflectTest;
    
    import java.lang.reflect.Method;
    
    /**
     * 通过获取类类型,进而获取Method对象,进而调用类的方法,
     * 和直接通过类的对象来调用方法可以达到一样的效果,这里的示例调用了对象的三个方法
     * @author Wang
     *
     */
    public class MethodDemo1 {
        public static void main(String[] args) {
            
            // 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型,要获取print(int ,int )方法
            A a1 = new A();
            Class c = a1.getClass();
            
            // 2.获取方法 名称和参数列表来决定 getMethod获取的是public的方法 getDelcaredMethod自己声明的方法
            try {
                System.out.println("==================调用print(int a, int b)方法");
                // Method m = c.getMethod("print", new Class[]{int.class,int.class});
                Method m = c.getMethod("print", int.class, int.class);
                // 方法的反射操作
                // a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同
                // 方法如果没有返回值返回null,有返回值返回具体的返回值
                // Object o = m.invoke(a1,new Object[]{10,20});
                Object o = m.invoke(a1, 10, 20);
                
                
                System.out.println("==================调用print(String a, String b)方法");
                
                
                // 获取方法print(String,String)
                Method m1 = c.getMethod("print", String.class, String.class);
                // 用方法进行反射操作
                // a1.print("hello", "WORLD");
                o = m1.invoke(a1, "hello", "WORLD");
                
                
                System.out.println("===================调用无参的print方法");
                
                
                // Method m2 = c.getMethod("print", new Class[]{});
                Method m2 = c.getMethod("print");
                // m2.invoke(a1, new Object[]{});
                m2.invoke(a1);
                
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    }
    
    class A {
        public void print() {
            System.out.println("helloworld");
        }
    
        public void print(int a, int b) {
            System.out.println(a + b);
        }
    
        public void print(String a, String b) {
            System.out.println(a.toUpperCase() + "," + b.toLowerCase());
        }
    }
    
    更多相关内容
  • 主要介绍了Java反射机制及Method.invoke详解,本文讲解了JAVA反射机制、得到某个对象的属性、得到某个类的静态属性、执行某对象的方法、执行某个类的静态方法等内容,需要的朋友可以参考下
  • Java反射Method.invoke()的使用 在实习的过程中看到了项目中多次用到了反射,并且是method.invoke()的使用,便自己尝试一下。 首先创建三个类,一个Animal,一个Cat一个Dog分别继承Animal // 父类 public class ...

    Java反射之Method.invoke()的使用

    在实习的过程中看到了项目中多次用到了反射,并且是method.invoke()的使用,便自己尝试一下。

    1. 首先创建三个类,一个Animal,一个Cat一个Dog分别继承Animal
    // 父类
    public class Animal {
        public void call(String name){
            System.out.println(name +"这是动物的叫声");
        }
    }
    
    // 子类
    public class Cat extends Animal {
        @Override
        public void call(String name) {
            System.out.println(name + "喵喵喵~~~~");
        }
    }
    
    // 子类
    public class Dog extends Animal {
        @Override
        public void call(String name) {
            System.out.println(name + "汪汪汪~~~");
        }
    }
    
    1. 在客户端中我们做如下尝试:

    尝试一

        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            Class<Animal> animalClass = Animal.class;	// 类型类是父类
            Method call = animalClass.getDeclaredMethod("call",String.class);// 获得里面的call方法
            Cat cat = new Cat();
            call.invoke(cat,"achao");	// 传入Cat实例
        }
    
    // 执行结果
    // achao喵喵喵~~~~
    

    当然,我们在method.invoke()中传递一个dog的实例时,执行的是dog中的方法。

    尝试二

        public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            Class<Cat> catClass = Cat.class;// 类型类是Cat
            Method call = catClass.getDeclaredMethod("call",String.class);
            Cat cat = new Cat();
            call.invoke(cat,"achao"); // 传入Cat实例
        }
    // 结果是显然的,执行的是“achao喵喵喵~~~~”
    

    尝试三

            public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
                Class<Cat> catClass = Cat.class;// 类型类是Cat
                Method call = catClass.getDeclaredMethod("call",String.class);
                Animal animal = new Animal();
                call.invoke(animal,"achao");// 传入Animal实例
            }
    
    // 结果是报错:java.lang.IllegalArgumentException:
    

    尝试到这里我们可以猜想,当我们的类型类对象是一个子类的时候,我们想传递一个父类去执行里面具体的方法(先不管具体执行的是谁的方法),我们常规的想法是总会执行成功一个方法吧,但是,结果就是报错了。

    所以我得出结论:

    当通过某个类反射得到的method对象,使用method.invoke()执行某个实例的时候,这个实例 instance of 这个类必须是true,否则报错;如果这个实例重写了这个类的方法,则执行这个实例所对应的方法;如果没有,还是执行这个类的方法。

    展开全文
  • java反射机制描述及Method.invoke解释
  • 主要介绍了详解JavaMethodInvoke方法,需要的朋友可以参考下
  • Reflection APIJava Method.invoke()反射调用一个方法java.lang.reflect.Method.invoke() 方法来反射调用一个方法,当然一般只用于正常情况下无法直接访问的方法(比如:private 的方法,或者无法或者该类的对象)。...

    首页 > 基础教程 > 反射 > Reflection API

    Java Method.invoke()反射调用一个方法

    java.lang.reflect.Method.invoke() 方法来反射调用一个方法,当然一般只用于正常情况下无法直接访问的方法(比如:private 的方法,或者无法或者该类的对象)。

    定义

    public native Object invoke(Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;

    参数:

    第一个参数是方法属于的对象(如果是静态方法,则可以直接传 null)

    第二个可变参数是该方法的参数

    返回值:

    Object

    异常:

    如果调用的方法有抛出异常,异常会被 java.lang.reflect.InvocationTargetException 包一层

    源码分析

    public final class Method extends AccessibleObject implements GenericDeclaration, Member {

    // ...

    private volatile MethodAccessor methodAccessor;

    // For sharing of MethodAccessors. This branching structure is

    // currently only two levels deep (i.e., one root Method and

    // potentially many Method objects pointing to it.)

    private Method              root;

    // ...

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

    {

    if (!override) {

    if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {

    Class caller = Reflection.getCallerClass(1);

    Class targetClass = ((obj == null || !Modifier.isProtected(modifiers))

    ? clazz

    : obj.getClass());

    boolean cached;

    synchronized (this) {

    cached = (securityCheckCache == caller)

    && (securityCheckTargetClassCache == targetClass);

    }

    if (!cached) {

    Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);

    synchronized (this) {

    securityCheckCache = caller;

    securityCheckTargetClassCache = targetClass;

    }

    }

    }

    }

    if (methodAccessor == null) acquireMethodAccessor();

    return methodAccessor.invoke(obj, args);

    }

    // NOTE that there is no synchronization used here. It is correct

    // (though not efficient) to generate more than one MethodAccessor

    // for a given Method. However, avoiding synchronization will

    // probably make the implementation more scalable.

    private void acquireMethodAccessor() {

    // First check to see if one has been created yet, and take it

    // if so

    MethodAccessor tmp = null;

    if (root != null) tmp = root.getMethodAccessor();

    if (tmp != null) {

    methodAccessor = tmp;

    return;

    }

    // Otherwise fabricate one and propagate it up to the root

    tmp = reflectionFactory.newMethodAccessor(this);

    setMethodAccessor(tmp);

    }

    // ...

    }

    Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理。 每个实际的Java方法只有一个对应的Method对象作为root,。这个root是不会暴露给用户的,而是每次在通过反射获取Method对象时新创建Method对象把root包装起来再给用户。在第一次调用一个实际Java方法对应得Method对象的invoke()方法之前,实现调用逻辑的MethodAccessor对象还没创建;等第一次调用时才新创建MethodAccessor并更新给root,然后调用MethodAccessor.invoke()真正完成反射调用。

    例子

    public class MethodInvoke extends BaseTestClass {

    private boolean checkString(String s) {

    printFormat("checkString: %s\n", s);

    return TextUtils.isEmpty(s);

    }

    private static void saySomething(String something) {

    System.out.println(something);

    }

    private String onEvent(TestEvent event) {

    System.out.format("Event name: %s\n", event.getEventName());

    return event.getResult();

    }

    static class TestEvent {

    private String eventName;

    private String result;

    public TestEvent(String eventName, String result) {

    this.eventName = eventName;

    this.result = result;

    }

    public String getResult() {

    return result;

    }

    public String getEventName() {

    return eventName;

    }

    }

    public static void main(String[] args) {

    try {

    Class < ?>cls = Class.forName("net.sxkeji.shixinandroiddemo2.test.reflection.MethodInvoke");

    MethodInvoke object = (MethodInvoke) cls.newInstance();

    Method[] declaredMethods = cls.getDeclaredMethods();

    for (Method declaredMethod: declaredMethods) {

    String methodName = declaredMethod.getName(); //获取方法名

    Type returnType = declaredMethod.getGenericReturnType(); //获取带泛型的返回值类型

    int modifiers = declaredMethod.getModifiers(); //获取方法修饰符

    //                declaredMethod.setAccessible(true);

    if (methodName.equals("onEvent")) {

    TestEvent testEvent = new TestEvent("shixin's Event", "cuteType");

    try {

    Object invokeResult = declaredMethod.invoke(object, testEvent);

    System.out.format("Invoke of %s, return %s \n", methodName, invokeResult.toString());

    } catch(InvocationTargetException e) { //处理被调用方法可能抛出的异常

    Throwable cause = e.getCause();

    System.out.format("Invocation of %s failed:  %s\n", methodName, cause.getMessage());

    }

    } else if (returnType == boolean.class) {

    try {

    declaredMethod.invoke(object, "shixin's parameter");

    } catch(InvocationTargetException e) {

    Throwable cause = e.getCause();

    System.out.format("Invocation of %s failed:  %s\n", methodName, cause.getMessage());

    }

    } else if (Modifier.isStatic(modifiers) && !methodName.equals("main")) { //静态方法,调用时 object 直接传入 null

    try {

    declaredMethod.invoke(null, "static method");

    } catch(InvocationTargetException e) {

    Throwable cause = e.getCause();

    System.out.format("Invocation of %s failed:  %s\n", methodName, cause.getMessage());

    }

    }

    }

    } catch(ClassNotFoundException e) {

    e.printStackTrace();

    } catch(InstantiationException e) {

    e.printStackTrace();

    } catch(IllegalAccessException e) {

    e.printStackTrace();

    }

    }

    }

    执行结果:

    checkString: shixin's parameter

    Invocation of checkString failed:  Stub!

    Event name: shixin's Event

    Invoke of onEvent, return cuteType

    static method

    Process finished with exit code 0

    总结

    1. Method.invoke()本身要用数组包装参数;而且每次调用都必须检查方法的可见性(在Method.invoke()里),也必须检查每个实际参数与形式参数的类型匹配性(在NativeMethodAccessorImpl.invoke0()里或者生成的Java版MethodAccessor.invoke()里)

    2. Method.invoke()就像是个独木桥一样,各处的反射调用都要挤过去,在调用点上收集到的类型信息就会很乱,影响内联程序的判断,使得Method.invoke()自身难以被内联到调用方。

    版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。

    展开全文
  • java 反射中的method.invoke()方法详解

    千次阅读 2017-10-25 18:17:13
    method invoke() 反射


    public class TestReflect
    {
        public static void main(String[] args)
        {
            String [] names ={"tom","tim","allen","alice"};
            Class<?> clazz = Test.class;
            try
            {
                Method method = clazz.getMethod("sayHi", String.class);
                for(String name:names)
                    method.invoke(clazz.newInstance(),name);
            }catch (Exception e){
                e.printStackTrace();
             }
        }
    }
    class Test
    {
        public void sayHi(String name)
        {
            System.out.println("Hi "+name);
        }
    }

    输出结果

    Hi tom
    Hi tim
    Hi allen
    Hi alice






    Method method = clazz.getMethod(" 方法名字","方法的参数类型');



    method.invoke(" 要调用的方法的名字所隶属的对象实体",方法的参数值);


    这就是method的invoke的作用




    展开全文
  • method.invoke(single, new Object[]{ objects }); } } class Single { public void method(Object... objs) { System.out.println(Arrays.deepToString(objs)); } } 结果: [[fuck, ni, mei], 23] [1, fuck, [fuck,...
  • 错误信息: java.lang.IllegalArgumentException: argument type ... at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcces...
  • Java反射机制 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为:Java语言的反射...
  • javaMethod.invoke方法参数解析

    千次阅读 2022-01-25 15:15:38
    通过反射的机制,可以通过invoke方法来调用类的函数。invoke函数的第一个参数是方法的实例,如果该方法是静态方法,可以用null或者用类来代替,第二个参数是变长的,是调用该方法的参数。 package com.tn.class; ...
  • Java反射Methodinvoke方法实现

    千次阅读 2020-11-11 21:55:35
    以前写代码用到反射时,总是获取先获取Method,然后传入对应的Class实例对象执行方法。然而前段时间研究invoke方法时,发现invoke方法居然包含多态的特性,这是以前没有考虑过的一个问题。那么Method.invoke()方法的...
  • java反射机制详解及Method.invoke解释.pdf
  • java反射机制详解 及 Method.invoke解释

    千次阅读 2017-08-22 00:35:43
    Java反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的...
  • 近期看到 invoke 方法第一个参数的另外一种传法,如下: public class Event { public static final String TAG= "Event"; public static void test(){ Log.d(TAG, "Event test: "); } } Class<?> aClass...
  • 在使用method.invoke()方法时,遇到了一个问题,就是,在传递第二个参数时,如果传递的是数组,如果数组中只有一个数据时,不需要强转,也不能强转,而如果数组中数据长度大于1时,需要强转成object.如下图: 首先,明确一下...
  • Method.invokeMethodAccess.invoke的区别

    千次阅读 2017-09-13 15:37:56
    本篇文章主要介绍java.reflect.Method与com.esotericsoftware.reflectasm.MethodAccess的区别。不多说,先贴上代码。 package org; import com.alibaba.fastjson.JSON; import ...
  • Method.invoke()用途广泛 例子 import java.lang.reflect.Method; public class MethodTest { public static void main(String[] args) throws Exception { Class<?> clz = Class.forName(...
  • java反射Methodinvoke方法实现

    万次阅读 多人点赞 2018-07-29 00:31:48
    以前写代码用到反射时,总是获取先获取Method,然后传入对应的Class实例对象执行方法。然而前段时间研究invoke方法时,发现invoke方法居然包含多态的特性,这是以前没有考虑过的一个问题。那么Method.invoke()方法的...
  • 使用method.invoke()之后,使用try{} catch (自定义异常){}进行捕获,竟然没有捕获到,最终定位到原因是:如果方法中直接抛出异常,通过反射进行调用时,会抛出InvocationTargetException异常 代码 自定义异常 ...
  • method.invoke方法如何捕获异常

    千次阅读 2020-05-25 20:33:32
    其实java认为用反射来调用方法时,jvm不能在编译期间确定方法的throws 类型,所以方法可能抛出的异常jvm也不能动态确定其类型,而统一抛出InvocationTargetException。 我们采用下面方法捕获异常: t...
  • Java反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的...
  • Java反射Methodinvoke方法的用法

    千次阅读 2021-02-26 14:41:54
    import java.lang.reflect.Method;public class InvokeTester {public int add(int param1, int param2) {return param1 + param2;}public String echo(String mesg) {return "echo" + mesg;}public static void mai...
  • 这篇文章主要介绍了详解JavaMethodInvoke方法,需要的朋友可以参考下在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过...
  • 用传统的OOP思想来说,任何一个你写好的且编译过的生成的Class文件,在被类加载器加载后,都会对应有一个java.lang.Class这个类的实例。所以说,每个类的自有的方法属性(类结构)自然被包含在了这个对应的实例上,...
  • method().invoke()

    2022-03-07 11:29:00
    method().invoke() 先理解下Java的反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象...
  • 文章目录问题1.动态代理使用Kotlin书写报错描述思考解决 问题 1.动态代理使用Kotlin书写报错 ... java.lang.IllegalArgumentException: method android.app.IActivityManager$Stub$Proxy.getActivityDispla...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 113,051
精华内容 45,220
关键字:

java反射method.invoke