1

我正在尝试使用反射包访问私有方法。我能够访问私有方法,但我在发送参数时遇到了问题。

我的代码如下所示:

Sample s = new Sample();
java.lang.reflect.Method method [] = Sample.class.getDeclaredMethods();
System.out.println("Total Number of methods in Sample class"+method.length);
for (int i=0; i<method.length;i++) {
    String methodName=method[i].getName();
    System.out.println("Method Name is "+methodName);
    if (methodName.equalsIgnoreCase("sampleTest1")) {
        method[i].setAccessible(true);
        //This is calling sampleTest1 method; it's not working
        //System.out.println(method[i].invoke(s, new String[]{"ABC"});
    } else {
        //This is calling sampleTest method and it's working
        System.out.println(method[i].invoke(s, null));
    }
}

我的示例类:

public class Sample {
    private String sampleTest(){
         return "Private Method";
    }

    private String sampleTest1(String abc){
    return "Private Method";
    }
}

我可以访问 sampleTest() 方法,但我不知道如何将参数传递给 sampleTest1() 方法。你能帮忙吗?

输出

Total Number of methods in Sample class2

Method Name is sampleTest

Exception in thread "main" java.lang.IllegalAccessException: Class com.sarma.reflection.sample.SampleTest can not access a member of class com.sarma.reflection.sample.Sample with modifiers "private"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
    at java.lang.reflect.Method.invoke(Method.java:588)
    at com.sarma.reflection.sample.SampleTest.main(SampleTest.java:26)
4

4 回答 4

4

您需要将null传递给的参数转换为invoke().

 System.out.println(method[i].invoke(s, (Object)null));

否则它认为你正在调用没有参数的底层方法,即。一个null Object[]。通过强制转换,编译器(和运行时)知道您将null对象作为 varargs 中的唯一元素传递Object[]

编辑后:您是否删除了setAccessible(true)? 你已经把你的if-else. 利用

if(methodName.equalsIgnoreCase("sampleTest1")){
    method[i].setAccessible(true);
    System.out.println(method[i].invoke(s, (Object) null));
} else{
    method[i].setAccessible(true);
    System.out.println(method[i].invoke(s, null));
}

或者把method[i].setAccessible(true);外面的if-else

于 2013-09-13T15:27:38.200 回答
1

这应该是一种通用方法。我们检索方法参数并创建同一类的实例,以作为方法参数传递。

public class Sample
{
  @SuppressWarnings ("unused")
  private String sampleTest() { return "Private Method"; }

  @SuppressWarnings ("unused")
  private String sampleTest1(String s) { return "Private Method: String"; }

  @SuppressWarnings ("unused")
  private String sampleTest2(Object o) { return "Private Method: Object"; }

  @SuppressWarnings ("unused")
  private String sampleTest3(ArrayList<String> list) { return "Private Method: List<String>"; }

  public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException,
      InstantiationException
  {
    Sample s = new Sample();
    java.lang.reflect.Method method[] = Sample.class.getDeclaredMethods();
    for (int i = 0; i < method.length; i++)
    {
      Method m = method[i];
      if (m.getModifiers() == Modifier.PRIVATE)
      {
        String methodName = m.getName();
        System.out.println(methodName);
        m.setAccessible(true);

        Class<?>[] pType = m.getParameterTypes();
        Object[] params = new Object[pType.length];
        for (int j = 0; j < pType.length; j++)
        {
          params[j] = pType[j].newInstance();
        }
        if (params.length == 0)
        {
          System.out.println(method[i].invoke(s));
        }
        else if (params.length == 1)
        {
          System.out.println(method[i].invoke(s, params[0]));
        }
      }
    }
  }
}

这种方法只有在方法的参数有一个没有参数的构造函数或者可以被实例化时才有效。例如。List是一个接口,因此不工作,Double有一个非空的 c'tor,也不能工作等。

输出

sampleTest
Private Method
sampleTest1
Private Method: String
sampleTest2
Private Method: Object
sampleTest3
Private Method: List<String>
于 2013-09-13T15:45:28.683 回答
1

您需要将一个 Object 数组作为第二个参数传递给 invoke():

method[i].invoke(s, new Object[] { "ABC" });

或没有参数:

method[i].invoke(s, (Object[]) null);
于 2013-09-13T15:38:30.277 回答
0

IT 工作

Sample s = new Sample();
        java.lang.reflect.Method method [] = Sample.class.getDeclaredMethods();
        System.out.println("Total Number of methods in Sample class"+method.length);
        for(int i=0; i<method.length;i++){
            String methodName=method[i].getName();
            System.out.println("Method Name is "+methodName);
            method[i].setAccessible(true);
            if(methodName.equalsIgnoreCase("sampleTest1")){
            method[i].setAccessible(true);
            //This is calling sampleTest1 method, ITs not workoing
            System.out.println(method[i].invoke(s, new String[]{"ABC"}));
            } else{
            //This is calling sampleTest method its working
            System.out.println(method[i].invoke(s, null));
            }
    }
    }

public class Sample {

    private String sampleTest(){
        return "Private Method";
    }

    private String sampleTest1(String abc){
        return "Private Method "+abc;
    }
}

输出

Sample 类 2 中的方法总数 方法名称为 sampleTest1 私有方法 ABC 方法名称为 sampleTest 私有方法

于 2013-09-13T15:40:54.027 回答