无法使用反射包将变量传递给私有方法

时间:2013-09-13 15:21:03

标签: java reflection

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

我的代码如下:

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 个答案:

答案 0 :(得分: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

之外

答案 1 :(得分:1)

你需要传递一个Object数组作为invoke()的第二个参数:

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

或没有参数:

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

答案 2 :(得分: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]));
        }
      }
    }
  }
}

只有当方法的参数具有没有参数的构造函数或者根本无法实例化时,此方法才有效。 E. g。 List是一个接口,因此无法正常工作,Double有一个非空的c'tor,也没有工作等。

<强>输出

sampleTest
Private Method
sampleTest1
Private Method: String
sampleTest2
Private Method: Object
sampleTest3
Private Method: List<String>

答案 3 :(得分: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 class2中的方法总数 方法名称为sampleTest1 私人方法ABC 方法名称为sampleTest 私人方法