Java反射调用某个类的方法(带参数和不带参数)

Class类:

public getDeclaredMethod( name,                                  <?>... parameterTypes)                           throws ,                                  

返回一个 Method对象,该对象反映此 Class对象所表示的类或接口的指定已声明方法。name参数是一个 String,它指定所需方法的简称,parameterTypes参数是 Class对象的一个数组,它按声明顺序标识该方法的形参类型。如果在某个类中声明了带有相同参数类型的多个方法,并且其中有一个方法的返回类型比其他方法的返回类型都特殊,则返回该方法;否则将从中任选一个方法。如果名称是 "<init>” 或 “<clinit>",则引发一个 NoSuchMethodException。 

参数:

name- 方法名 

parameterTypes- 参数数组 

返回:

该类与指定名和参数相匹配的方法的 Method对象 

抛出:

- 如果找不到匹配的方法。 

- 如果 name为 null

- 如果存在安全管理器 s,并满足下列任一条件: 

·        调用 拒绝访问已声明方法 

·        调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对 的调用拒绝访问该类的包 

从以下版本开始:

JDK1.1 

 

 

Method类:

 

public invoke( obj,                       ... args)                throws ,                       ,                       

对带有指定参数的指定对象调用由此 Method对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。 

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

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

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

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

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

参数:

obj- 从中调用底层方法的对象 

args- 用于方法调用的参数 

返回:

使用参数 args在 obj上指派该对象所表示方法的结果 

抛出:

- 如果此 Method对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。 

- 如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。 

- 如果底层方法抛出异常。 

- 如果指定对象为 null,且该方法是一个实例方法。 

- 如果由此方法引起的初始化失败。

 

这个动态调用类的方法非常好用,可以根据字符串动态调用某个类的方法,灵活性大,但记住反射是比较耗效率,要保留的用。可以这么用,通过一个文本来解析,动态实现某个类的计算方法,通过一个文本就可以方便的调用方法的机制。比较灵活。

 

 

下面是代码,已经封装好了:

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jijing.method;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Administrator
 * 用来通过类名反射当前类的某个方法,包括带参数的方法,当然只可以是public的方法
 */
public class ClassMethod {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        MyMethod m=new MyMethod();
        getMethod("show",m,null);//这个方法可以根据一个字符串来动态创建某个类的相应方法,这个思路非常好。
        getMethod("show",m,new Object[]{20});
        //包括自定义类 
        getMethod("show",m,new Object[]{100,"今天天气不错",new NewClass()});
    }
    
    /**
     * 
     * @param className 类的路劲
     * @return 返回Class的类信息 
     */
    public static Class getclass(String className){
        Class c=null;
        try {
            c=Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
        }
        return c;
    }
    
    /**
     * 
     * @param MethodName 
     * @param o           调用此方法的对象
     * @param paras       调用的这个方法的参数参数列表
     */
    public static void  getMethod(String MethodName,Object o,Object []paras){
         Class c[]=null;
         if(paras!=null){//存在
             int len=paras.length;
             c=new Class[len];
             for(int i=0;i<len;++i){
                 c[i]=paras[i].getClass();
             }
         }
        try {
            Method method=o.getClass().getDeclaredMethod(MethodName,c);
            try {
                method.invoke(o,paras);//调用o对象的方法
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

/**
 * 
 * @author Administrator
 *   反射这个类的某个方法
 */
class MyMethod{
    public MyMethod(){
    }
    
    /**
     * 
     */
    public void show(){
        System.out.println("我是MyMethod");
    }
    
    /**
     * 
     * @param temp 带参数的的
     */
    public void show(Integer temp){
        System.out.println("**************************="+temp.intValue());
    }
    
    public void show(Integer a,String name,NewClass nc){
        System.out.println("Integer="+a+" name="+name+" NewClass="+nc);
    }
}

class NewClass{
    public void print(){
        System.out.println("我是NewClass()");
    }
    @Override
    public String toString(){
        return "我是NewClass";
    }
}

 

上面封装的方法是:

 

 

/**
     * 
     * @param MethodName 
     * @param o           调用此方法的对象
     * @param paras       调用的这个方法的参数参数列表
     */
    public static void  getMethod(String MethodName,Object o,Object []paras){
         Class c[]=null;
         if(paras!=null){//存在
             int len=paras.length;
             c=new Class[len];
             for(int i=0;i<len;++i){//这里不是java内置类基本数据是不支持的,请一步一步完成,可以参考我的上篇文章<Java通过反射创建对象>
                 c[i]=paras[i].getClass();
             }
         }
        try {
            Method method=o.getClass().getDeclaredMethod(MethodName,c);
            try {
                method.invoke(o,paras);//调用o对象的方法
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ClassMethod.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

 

 

注意:上面的方法是不支持内置类,因为内置类没有进行基本数据的转换,所以无法完成。为了可以完全正常运行,请转换上面的代码。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以使用Java反射机制中的getDeclaredMethod()方法来获取有不定参数方法。该方法需要两个参数方法名称和参数型。在参数型中,您可以使用“...”来表示不定参数。例如,如果您要获取一个名为“myMethod”的方法,它有一个字符串参数和一个不定参数,则可以使用以下代码: Class<?> clazz = MyClass.class; Method method = clazz.getDeclaredMethod("myMethod", String.class, String[].class); 请注意,这里的“String[].class”表示一个字符串数组,它可以接受任意数量的字符串参数。 ### 回答2: 在JAVA中,使用反射获取有不定参数方法可以通过以下步骤实现。 1. 首先,通过Class的forName方法获取目标的Class对象。例如,如果我们要获取名为"TestClass"的的Class对象,可以使用以下代码: Class<?> clazz = Class.forName("TestClass"); 2. 然后,使用getMethod或getDeclaredMethod方法获取目标方法Method对象。其中getMethod方法用于获取公共方法,getDeclaredMethod方法用于获取所有方法,包括私有方法。需要注意的是,方法名要与目标方法相匹配。如果目标方法有不定参数的,则需要在方法名后面加上三个点(...)来表示。例如,我们要获取名为"testMethod"的有不定参数方法,可以使用以下代码: Method method = clazz.getMethod("testMethod", String[].class); 3. 最后,可以通过Method对象的invoke方法调用目标方法。例如,如果我们要调用testMethod方法,可以使用以下代码: Object result = method.invoke(null, (Object) new String[]{"param1", "param2"}); 需要注意的是,invoke方法的第一个参数调用方法的对象,如果目标方法是静态方法,则可以将该参数设置为null。之后的参数可以按照目标方法参数型顺序传入。 总结来说,通过使用Class的forName方法获取Class对象,再使用getMethod或getDeclaredMethod方法获取Method对象,最后使用invoke方法调用目标方法,就可以实现获取有不定参数方法并进行调用。 ### 回答3: 在Java中,通过反射获取有不定参数方法可以使用`getDeclaredMethod`方法。不定参数可以理解为方法参数个数是可变的。 首先,我们需要使用`Class`的`getDeclaredMethod`方法。这个方法接受两个参数方法的名称和参数型。在参数型位置上,我们可以使用"..."表示不定参数。例如,如果要获取一个名为`methodName`且有不定参数方法,可以使用以下代码: ```java Class<?> clazz = targetObject.getClass(); Method method = clazz.getDeclaredMethod("methodName", parameterTypes); ``` 其中,`targetObject`是调用方法的对象,`parameterTypes`是一个数组,包含了方法参数型。 在参数型中,不定参数会被视为数组型。例如,如果方法定义为`method(String... strs)`,则在参数型中应该传入`String[].class`。 获取到方法后,可以通过`method.invoke(targetObject, parameters)`来调用这个方法,其中`paramters`是一个包含实际参数值的数组。 需要注意的是,由于不定参数的特殊性,传入的实际参数值应该符合方法参数的个数和型。如果传入的实际参数个数与不定参数个数不匹配,或者传入的参数型与不定参数的元素型不匹配,则会抛出`IllegalArgumentException`异常。 总结来说,通过反射获取有不定参数方法,就是使用`getDeclaredMethod`方法,并在参数型中使用`"..."`来表示不定参数的数组型。获取到方法后,可以使用`invoke`方法调用这个方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值