如何通过反射访问一个类的私有方法

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过反射访问一个类的私有方法相关的知识,希望对你有一定的参考价值。

情况是这样的,博主要测试一个Java类,但是这个类的所有方法都是私有的。

以方法readExprFromFile为例,步骤写在测试类的注释里。

参考 调用方法 - 廖雪峰的官方网站

被测类

package net.mooctest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.regex.*;

import java.io.*;

public final class ProblemSolver 

  private static void readExprFromFile(HashMap<String, String> options) 
      StringBuilder builder = new StringBuilder();
      String varOrder = "";
      try (BufferedReader br = new BufferedReader(new FileReader(options.get("inFile")))) 
        varOrder = br.readLine();
        String line;
        while ((line = br.readLine()) != null) 
          if (!line.startsWith("//")) 
            if (builder.length() != 0) builder.append(" & ");
            builder.append(line);
          
        
       catch (Exception e) 
        System.err.println("Error encountered reading file");
        System.err.println(e);
        System.exit(1);
      

      String expr = builder.toString();
      options.put("expression", expr);

      // TODO: make this better
      if (!options.containsKey("order")) options.put("order", varOrder);
      createAndSolveBDD(options);
  

  private static void createAndSolveBDD(HashMap<String, String> options) 
    try 
      BoolExpression expr = new BoolExpression(options.get("expression"));

      BDD bdd = null;
      if (options.containsKey("order")) 
        String order = options.get("order");
        bdd = (order.equals("random")) ? BDD.ofRandomOrder(expr) : BDD.of(expr, parseOrder(order));
       else 
        bdd = BDD.of(expr);
      

      List<String> vars = bdd.getVariables();
      double numSolutions = bdd.getNumSolutions();

      Map<String, Boolean> solution = (numSolutions != 0) ? bdd.anySat() : null;

      reportStats(options.get("expression"), vars, numSolutions, BDD.getNumNodes(), solution);

      if (options.containsKey("outFile")) 
        bdd.outputGraph(options.get("outFile"));
      

     catch (Exception e) 
      System.err.println("Error encountered while solving expression.");
      System.err.println(e);
      System.exit(1);
    
  

  private static void reportStats(String expr, List<String> vars, double numSolutions,
        int numNodes, Map<String, Boolean> soln) 
    System.out.println("Statistics for expression: " + expr);
    System.out.println("- - - - - - -");

    System.out.print("\\nVariable Ordering: ");
    System.out.println(vars);

    System.out.print("\\nNumber of BDD Nodes: ");
    System.out.println(numNodes);

    System.out.print("\\nNum solutions: ");
    System.out.println(numSolutions);

    if (soln != null) 
      System.out.print("\\nSatisfying solution: ");
      System.out.println(soln);
    
  

  // TODO: Add option to specify variable ordering
  private static HashMap<String, String> parseOptions(String args[]) 
    HashMap<String, String> result = new HashMap<String, String>();
    for (int i = 0; i < args.length; i++) 
      String arg = args[i];
      if (arg.length() > 0 && arg.charAt(0) == '-') 

        if (arg.equals("-file") || arg.equals("-f")) 
          try 
            result.put("inFile", args[i+1]);
            i++;
           catch (ArrayIndexOutOfBoundsException e) 
            System.err.println("Expecting file name after -file flag");
            System.exit(1);
          
        

        if (arg.equals("-o") || arg.equals("-out")) 
          try 
            result.put("outFile", args[i+1]);
            i++;
           catch (ArrayIndexOutOfBoundsException e) 
            System.err.println("Expecting file name after -out flag");
            System.exit(1);
          
        

        if (arg.equals("-order")) 
          try 
            result.put("order", args[i+1]);
            i++;
           catch (ArrayIndexOutOfBoundsException e) 
            System.err.println("Expecting variable ordering after -order flag");
            System.exit(1);
          
        
       else 
        // Assume this argument is a boolean expression to parse;
        result.put("expression", arg);
      
    

    return result;
  

  private static List<String> parseOrder(String orderStr) 
    return Arrays.asList(orderStr.split(Pattern.quote(" ")));
  

测试类

package net.mooctest;

import static org.junit.Assert.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

import org.junit.Test;

public class ProblemSolverTest 

	@Test
	public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException 
		//获取这个类的Class实例
		Class cls = ProblemSolver.class;
		
		HashMap<String, String> options = new HashMap<String, String>();
		
		//获取想要的方法
		Method m = cls.getDeclaredMethod("readExprFromFile", HashMap.class);
		
		//修改方法的可见性
		m.setAccessible(true);
		
		//调用方法
		m.invoke(null, options);
		
		
	


以上是关于如何通过反射访问一个类的私有方法的主要内容,如果未能解决你的问题,请参考以下文章

廖雪峰Python总结4

通过反射访问父类的私有成员

如何(通过反射调用一个类的私有方法)

java里一个私有的属性如何在其他类里面进行访问?

如何通过反射访问私有方法和私有数据成员?

廖雪峰Java2面向对象编程-4抽象类和接口-1抽象类