精华内容
下载资源
问答
  • Java - 如何通过反射调用对象方法
    万次阅读
    2019-03-17 15:15:37

    分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 

    请看下面的代码:

    import java.lang.reflect.Method;
     
    class MethodInvokeTest {
     
        public static void main(String[] args) throws Exception {
            String str = "hello";
            Method m = str.getClass().getMethod("toUpperCase");
            System.out.println(m.invoke(str));  // HELLO
        }
    }

     

    更多相关内容
  • 主要介绍了java通过反射创建对象调用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 该篇文章主要介绍当我们碰到参数或者返回值是一个对象时,如何通过frida反射调用对象方法(methods)与获取该对象的字段(fields)。感兴趣的朋友可以下载下来看看,了解了解
  • 主要介绍了Java使用反射调用方法,结合实例形式分析了java使用反射调用对象方法的相关操作技巧,需要的朋友可以参考下
  • 下面小编就为大家带来一篇Java反射根据不同方法名动态调用不同的方法(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了C#中方法的直接调用反射调用与Lambda表达式调用对比,本文着重讲解了方法的三种调用方法以及它们的性能对比,需要的朋友可以参考下
  • Java反射机制,万物皆对象,class也是一个类的对象,通过类类型,反射获得类的成员属性,构造方法,成员方法,并调用类中的方法,也可以调用私有方法
  • 一.Java反射拿到调用对象方法 1.通过Class.forName(“包名+方法的类名”)拿到方法对象; 如:Class<?> clazz = Class.forName("ReflectionTest");  也可以通过实例,获取方法对象...

     

    一.Java反射拿到调用对象的方法

    1.通过Class.forName(“包名+方法的类名”)拿到方法的对象;

    如:Class<?> clazz = Class.forName("ReflectionTest");

            也可以通过实例,获取方法的对象类,

            如:String str = "test , reflection";

            Class<?> clazz = str.getClass();

    2.明确反射方法名称 ;

    3.明确方法的参数类型,就可以拿到对象的方法。

    如:Method method = clazz.getMethod("test",String.class,int.class);

     

     

     二.接着就是invoke()调用方法了:

    1.实例化对象,可以直接调用已创建的对象,也可以newInstance()一个。

    2.确定具体方法的参数

    如:     Object obj1 = method.invoke(clazz.newInstance(),"xiaojun",23);

           System.out.println("直接反射:"+obj1);

     

     

    三.补充一些关于Java反射的知识:

    Java反射的作用:在Java代码编译时,可以通过反射访问装载到JVM中类的内部信息。

    如: Clazz.getName()获取类的完整名字

                      getPackage()获取此类所属的包

                      getSuperclass() 获取父类对应的Class对象

                       getFiled(String name) 获得类的指定成员变量

                       getMethods() 获得类的public类型的方法

                       getMethod(String name, Class[] args) 获取类的指定方法

     

    四.具体实例:

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class ReflectionTest {
    	
    	public String test(String name ,int age) {
    		
    		return name+",今年"+age+"岁,是一个极富好奇心地乐观青年!";
    	}
    	
    	public static void main(String args[]) {
    		
    			String str = "test , reflection";
    			int len1 = str.length();
    			System.out.println("直接调用length() :"+len1);
    			
    			//反射String.length()方法
    			//直接填入调用该方法的对象str,这里不需要newInstance()
    			Object len2 = Reflection(str,str.getClass(),"length",null,null);
    			System.out.println("java 反射调用length() :"+len2);
    	
    			Class<?> clazz;
    		
    				try {
    					
    					//调用自己创建的函数,
    					//反射得到类 包名+类名,我这边没有包名就直接是 "ReflectionTest"
    					clazz = Class.forName("ReflectionTest");
    					
    					//直接java反射得到方法
    					Method method= clazz.getMethod("test",String.class,int.class);
    					Object obj1 = method.invoke(clazz.newInstance(),"xiaojun",23);
    					System.out.println("直接反射:"+obj1);
    					
    					
    					//创建函数完成反射
    				  //创建参数class 类型的数组
    					Class<?> cla[] = {String.class,int.class};
    					Object obj = Reflection(clazz.newInstance(),clazz,"test",cla,"小君",22);
    					System.out.println("创建函数完成反射: "+obj);
    					
    				
    				} catch (ClassNotFoundException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (InstantiationException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (IllegalAccessException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (NoSuchMethodException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (SecurityException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (IllegalArgumentException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				} catch (InvocationTargetException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    
    	}
    	
    	/*
    	 * 通过反射执行cclass的方法
    	 * @param   object  ---调到该方法的具体对象
    	 * @param   cclass  ---具体对象的class类型
    	 * @param   paramClasses ---反射方法中参数class类型
    	 * @param   methodName   ---反射方法的名称
    	 * @param   args    ----调用该方法用到的具体参数
    	 * 
    	 * 
    	 * */
    	public static Object Reflection(Object object ,Class<?> cclass,String methodName,Class<?>[] paramclasses, Object... args) {
    		
    		try {
    			
    			Method method = cclass.getMethod(methodName,paramclasses);
    			return method.invoke(object,args);
    			
    			
    		} catch (NoSuchMethodException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (SecurityException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InvocationTargetException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		return null;
    		
    	}
    
    }
    
        /* 运行结果:
            直接调用length() :17
            java 反射调用length() :17
            直接反射:xiaojun,今年23岁,是一个极富好奇心地乐观青年!
            创建函数完成反射: 小君,今年22岁,是一个极富好奇心地乐观青年!*/
    
    
    

    运行结果:

    直接调用length() :17
    java 反射调用length() :17
    直接反射:xiaojun,今年23岁,是一个极富好奇心地乐观青年!
    创建函数完成反射: 小君,今年22岁,是一个极富好奇心地乐观青年!

     

    欢迎加入我的Java与Android逆向开发交流QQ群,一起交流学习。

     

    展开全文
  • 以上是反射对象中不存在注入的情况下可以使用的方法,一旦涉及到注入的时候,直接使用clazz.newInstance()会导致原本对象中注入的内容变为空值,这里需要通过spring去获取对象bean。 package test ; import ...
    package test;
    /**
     * 测试类
     */
    public class TestService {
    	
    	public String testMethod(){
    		return "success test method";
    	}
    
    	private String testMethod(String param){
    		return "success test method param = " +param;
    	}
    
    	public String testMethod(String param1,String param2){
    		return "success test method param1 = " +param1 + " param2="+param2;
    	}
    	
    	public String testMethod(String param1,int param2){
    		return "success test method param1 = " +param1 + " param2="+param2;
    	}
    
    }
    
    package test;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import org.junit.Test;
    
    public class TestController {
    	@Test
    	public void testField() {
    	    try {
    	    	//根据类名获取所需类
    			Class<?> clazz = Class.forName("test.TestService");
    			//实例化对象
    			Object a = clazz.newInstance();
    			//获取对象中的所有方法,包括私有方法
    	    	Method[] methods = clazz.getDeclaredMethods();
    		    for (Method method : methods) {
    		    	//获取方法所需参数个数以及类型
    		        Object[] objs = null;
    		        if (method.getParameterTypes().length>0) {
    		        	objs = new Object[method.getParameterTypes().length];
    		        	int index = 0;
    		        	for (Object parameterType : method.getParameterTypes()) {
    		        		if (parameterType==String.class) {
    		        			objs[index++] = "a";
    						}else if (parameterType==Integer.class||parameterType==int.class) {
    						//可扩展为是否是数字类型
    		        			objs[index++] = 1;
    						}
    					}
    				}
    				//这里需要注意。检查方法是否为private,如果是需要设置方法的accessible
    				//否则会发生异常 java.lang.IllegalAccessException: Class test.TestController can not access a member of class test.TestService with modifiers "private"
    				//accessible 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
    		        if (Modifier.isPrivate(method.getModifiers())) {
    					method.setAccessible(true);
    				}
    				//携带请求参数,否则会发生异常 java.lang.IllegalArgumentException: wrong number of arguments
    		        Object o = method.invoke(a,objs);
    		        System.out.println(o);
    		    }
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    
    #输出结果
    success test method param1 = a param2=1
    success test method param1 = a param2=a
    success test method param = a
    success test method
    

    以上是反射对象中不存在注入的情况下可以使用的方法,一旦涉及到注入的时候,直接使用clazz.newInstance()会导致原本对象中注入的内容变为空值,这里需要通过spring去获取对象bean。

    package test;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestController {
    	
    	@Test
    	public void testField() {
    	    try {
    			//初始化spring
    	    	ApplicationContext ac = new ClassPathXmlApplicationContext(new String[] { "spring-test.xml" });
    			Class<?> clazz = Class.forName("test.TestService");
    			//获取bean而不是直接创建实例
    			Object a = ac.getBean(clazz);
    //			Object a = clazz.newInstance();
    	    	Method[] methods = clazz.getDeclaredMethods();
    		    for (Method method : methods) {
    		        Object[] objs = null;
    		        if (method.getParameterTypes().length>0) {
    		        	objs = new Object[method.getParameterTypes().length];
    		        	int index = 0;
    		        	for (Object parameterType : method.getParameterTypes()) {
    		        		if (parameterType==String.class) {
    		        			objs[index++] = "a";
    						}else if (parameterType==Integer.class||parameterType==int.class) {//可扩展为是否是数字类型
    		        			objs[index++] = 1;
    						}
    					}
    				}
    		        if (Modifier.isPrivate(method.getModifiers())) {
    					method.setAccessible(true);
    				}
    		        Object o = method.invoke(a,objs);
    		        System.out.println(o);
    		    }
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    }
    
    <!-- 对应的spring-test.xml文件 -->
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    	<!-- 配置要扫描的包 -->
    	<context:component-scan base-package="test"></context:component-scan>
    </beans>
    
    #输出结果
    success test method param1 = a param2=1
    success test method param1 = a param2=a
    success test method param = a
    test auto wired
    success test method
    
    展开全文
  • 通过反射访问一个对象方法,要确保此方法是可导出的,否则会报错。 对象类型 type Dog struct { } func (t Dog) T1(nums []int) { fmt.Println(nums) fmt.Println("t1") } func (t Dog) T2() { fmt.Println...

    通过反射访问一个对象的方法,要确保此方法是可导出的,否则会报错。

    对象类型

    type Dog struct {
    
    }
    
    func (t Dog) T1(nums []int) {
    	fmt.Println(nums)
    	fmt.Println("t1")
    }
    
    func (t Dog) T2() {
    	fmt.Println("t2")
    }
    

    列出对象的方法

    var tt Dog
    
    getType := reflect.TypeOf(tt)
    
    for i:= 0; i<getType.NumMethod();i++{
        met := getType.Method(i)
        fmt.Printf("%s, %s, %s, %d\n", met.Type, met.Type.Kind(), met.Name, met.Index)
    }
    

    打印

    func(main.Dog, []int), func, T1, 0
    func(main.Dog), func, T2, 1
    

    不知道你是否理解了这个输出结果,我们定义的对象的方法,比如 T2

    func (t Dog) T2() {
    	fmt.Println("t2")
    }
    

    实际上是这样的

    func(main.Dog){
    ...
    }
    

    使用下标调用方法

    调用方法使用 Call() 方法,但是搞笑的是这个 Call() 方法居然不是 Method 对象的(也就是上面的 met)而是 Value 对象的。

    // Call calls the function v with the input arguments in.
    // For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
    // Call panics if v's Kind is not Func.
    // It returns the output results as Values.
    // As in Go, each input argument must be assignable to the
    // type of the function's corresponding input parameter.
    // If v is a variadic function, Call creates the variadic slice parameter
    // itself, copying in the corresponding values.
    func (v Value) Call(in []Value) []Value {
    	v.mustBe(Func)
    	v.mustBeExported()
    	return v.call("Call", in)
    }
    

    在调用的时候会判断 Value 对象的 Kind 是否是 func

    好了,我们能否通过 Method 对象得到 Value 对象呢,答案是可以的。

    getType := reflect.TypeOf(tt)
    met := getType.Method(1)
    met.Func // 得到 value of method
    

    查看对象的 Kind

    fmt.Println(met.Func.Kind()) // func
    

    既然如此,我就可以调用 Call 方法了,此处以 T2 为例。

    met.Func.Call(nil)
    

    好家伙,报错了

    panic: reflect: Call with too few input arguments [recovered]
            panic: reflect: Call with too few input arguments
    

    说我少了参数,可是 T2 明明就没有参数啊,改一下 in 的值?。

    met.Func.Call([]reflect.Value{})
    

    依然报上面的错误。

    上面已经提到了,实际上,T2 的定义是这样的,就是参数的问题

    func(main.Dog)
    

    修改后

    met.Func.Call([]reflect.Value{reflect.ValueOf(tt)})
    

    果然可以正常调用了。

    关于 Call 方法的参数

    它的参数是 []Value,也就是 []reflect.Value,是 Value 对象的切片,切片的元素会按先后顺序填入到实参,比如方法有三个参数 arg1, arg2, arg3

    in := make([]reflect.Value, 3)
    in[0] := reflect.ValueOf(arg1)
    in[2] := reflect.ValueOf(arg2)
    in[3] := reflect.ValueOf(arg3)
    
    v.Call(in)
    

    如果没有参数,可以传 nil 或者[]reflect.Value{} 或者 make([]reflect.Value, 0)

    使用方法名调用方法

    getType := reflect.TypeOf(tt)
    met, ok := getType.MethodByName("T2")
    if !ok {
        panic("method not exist.")
    }
    met.Func.Call([]reflect.Value{reflect.ValueOf(tt)})
    

    简化调用

    上面已经演示了对象方法的调用,但是不符合我们实际的使用,正常的理解是 T2 是不应该传参的。

    要想达到这样的效果,我们要使用 reflect.ValueOf()来反射,此处使用 T1 为例。

    var tt Dog
    
    getValue := reflect.ValueOf(tt)
    m := getValue.Method(0)
    
    // 或者使用方法名称
    // m := getValue.MethodByName("T1")
    
    fmt.Println(m.Kind()) // func
    fmt.Println(m.Type()) // func([]int)
    
    arg := []int{1,2,3}
    m.Call([]reflect.Value{reflect.ValueOf(arg)})
    

    如果有多个参数,参考上面的写法。

    为什么这里不需要传入tt 呢,这是 TypeOfValueOf 反射的区别。

    但是前面也看到 了,met, ok := getType.MethodByName("T2") 要比 m := getValue.MethodByName("T2")多一个返回值用以判断方法是否存在,这一点很重要,否则就回报错,所以安全的方式为:

    if _, ok := getType.MethodByName(scheduleName); ok {
    	handler := getValue.MethodByName(scheduleName)
    	...
    	val := handler.Call([]reflect.Value{reflect.ValueOf(nums)})
    }
    

    Call() 的返回值为 []Value,切片中元素的个数就是返回值的个数,下标也一一对应。比如,增加一个 T3 方法

    func (t Dog) T3() bool {
    	return true
    }
    

    调用方法得到返回值

    getValue := reflect.ValueOf(tt)
    m := getValue.MethodByName("T3")
    re := m.Call([]reflect.Value{})
    intf := re[0].Interface() // interface{} 类型
    b := intf.(bool) // bool 类型
    
    展开全文
  • 若想调用非默认的构造器创建实例对象,需要先通过class对象获取构造器,在用构造器调用newInstance()方法创建。 例子:创建一个对象池,读取property文件,创建对象,spring依赖注入的基本原理也是这样实现...
  • /** * @author 万星明 * @version 创建时间:...public class 反射调用对象方法 { public static void main(String[] args) throws Exception { //创建反射对象 Class&lt;?&gt; clazz = Class.fo...
  • java基础-反射3(反射反射创建对象,操作对象属性,调用对象方法)前面通过学习,我们了解的运行时类型信息的基本原理,以及通过Class对象反射来获取运行时类型信息。下面来了解通过反射来创建对象,以及操作...
  • 通过Java反射机制调用方法

    千次阅读 2021-03-08 05:51:42
    通过Java反射机制调用方法//20210204写在前面:最近再把Java反射和注释知识点过一遍,在这里记一下重要的点,本文讲述反射机制创建对象调用方法主要任务:使用类反射机制实现对象创建以及方法调用与普通方式实现...
  • 反射:通过反射对象调用构造方法

    千次阅读 2018-11-04 10:52:50
    import java.lang.reflect.Constructor; /** * @author 万星明 * @version 创建时间:2018年10月26...public class 通过反射对象访问构造方法 { public static void main(String[] args) throws Exception { /...
  • 说明:第4步中是通过模拟我们从控制器中获取到的请求信息,从信息中解析出具体类的全路径,然后通过反射的方式获取实例对象,因为这些实例对象A类的子类,所以我们把他们统一强转成A对象,但是根据多态的原理我们...
  • Java试题-5:应用反射创建对象调用对象方法 反射为Java的高级技术应用
  • Java 反射创建get set方法及反射方法调用
  • 反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C++与.NET程序集之间传递复杂...
  • 反射:使用反射调用方法

    千次阅读 2017-07-03 14:04:20
    1.使用反射调用方法 1):获取方法所在类的字节码对象. 2):获取方法对象. 3):使用反射调用方法. ------------------------------------------------------------------------ 如何使用反射调用一个方法: 在...
  • Java中通过反射调用类中的方法

    千次阅读 2021-03-16 00:14:31
    Java中通过反射调用类中的方法,具体实现起来要注意两点:(1)通过 Class 类的 getMethod 方法取的 Method 对象,并设置调用方法时需要的参数类型。(2)使用 Method 方法调用 invoke 方法,并向该方法传递参数,其参数...
  • 通过Method对象的invoke方法调用实例方法 TestReflection4.java package study; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class TestReflection4 { ...
  • 例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。 1.2 反射常用类 Class类—可获取类和类的成员信息 Field类—可访问类的属性 Method...
  • 使用反射调用方法

    千次阅读 2019-07-10 21:14:39
    一代码 import java.util.*; import java.io.*; import java.lang.reflect.*; public class ... // 定义一个对象池,前面是对象名,后面是实际对象 private Map<String, Object> objectPool = new ...
  • java 反射 调用无参数方法?

    千次阅读 2021-02-26 14:56:35
    展开全部通过e68a84e8a2ad62616964757a686964616f31333337396236Java反射调用无参数方法,这是个测试用的例子,通过反射调用对象方法,代码如下:importjava.lang.reflect.Method;importjava.lang.reflect....
  • Java 反射调用静态方法

    千次阅读 2020-01-17 15:40:42
    专栏原创出处:github-源笔记文件 ,github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明。...一、使用 java.lang.reflect 包的 Method#invoke 调用 关键代码:Object invoke = method.invoke(null, Object......
  • Java反射机制既然可以拿到class对象,知道其中方法为啥不直接使用对象调用方法?而要invoke来调用对象的方法
  • 通过反射调用接口的方法

    千次阅读 2020-11-01 20:37:09
    答案参考这个:https://www.cnblogs.com/sueyyyy/p/9841857.html 后来查到一个方法,就是通过实现ApplicationContextAware中的方法,从spring上下文中取得bean对象,那么就不需要在business中写注解注入了接口了。...
  • java 反射调用set方法

    千次阅读 2021-02-12 15:29:39
    下面是小编为您带来的java 反射调用set方法,希望对大家有所帮助。java 反射调用set方法:import java.beans.PropertyDescriptor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ...
  • 在VS.Net中,有很多种方法动态调用对象的构造函数。一是通过Activator类的CreateInstance()方法。这个方法我们在Remoting中也用过。它实际上是在本地或从远程创建对象类型,或获取对现有远程对象的引用。它的方法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 325,799
精华内容 130,319
关键字:

对象调用方法是不是反射