0

I have a not so good legacy code involving in using the method of a private static class I was wondering if the method in such class can be called. Which I was writing test for. I know it can be done with reflection if this was a method but it isnt.

public class FiscalReport implements Report
    {
   private void readProductValueClass()
  {
   Connection dbc = null;
   Statement st = null;
   ResultSet rs = null;
   String q = null;
  try
  {
  dbc = db.getConnection();
  dbc.setAutoCommit(false);
  st = dbc.createStatement();

  routerClassMap = new HashMap();

  q = "SELECT * FROM sales_report";

  rs = st.executeQuery(q);
  while(rs.next())
  {
    ProductValueClassrc = new ProductValueClass(); // <---this new class 
                                                  //   is where it gets called...
   .....

  }

  private static class ProductValueClass
  {
    public String name;
    public String emp;
    public String sale;
    public String option;
    public String value;
    public Query q;
    public Query qr
    public Query sql;

    public String toString()
    {
      return
      "[" +
      name + ", " +
      emp + ", " +
      sale + ", " +
      option + ", " +
      values +
      "]";
    }

    public Query query()
    {
    return q.add(q(notEqual(qr)? null: sql));
    }
  }
}
logger
  • 1,983
  • 5
  • 31
  • 57

1 Answers1

0

I believe you are looking to create an instance of the private inner class? IF that is the case, this link already has a solution for you: Instantiate private inner class with java reflection

You can access the methods of ProductValueClass like this:

try {
    //creating parent object
    Object parent=new FiscalReport();

    //creating inner class object
    Class<?> innerClass=Class.forName("FiscalReport$ProductValueClass");

    //inner object must know type of outer class
    Constructor<?> constructor=innerClass.getDeclaredConstructor(FiscalReport.class);

    //private inner class has private default constructor
    constructor.setAccessible(true);
    //inner object must know about its outer object
    Object child = constructor.newInstance(parent);

    //invoking method on inner class object
    Method method = innerClass.getDeclaredMethod("wantedMethod",new Class<?>[]{});
    method.setAccessible(true);//in case of unaccessible method
    method.invoke(child,new Object[]{});

} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();

}

Since your inner class is static try this:

Class<?> clazz = Class.forName("FiscalReport$ProductValueClass");
Object c = clazz.newInstance();

Class<?> productValueClass = c.getClass();
Method toStringMethod = productValueClass.getMethod("toString", new Class<?>[] {});
toStringMethod.setAccessible(true);
System.out.println(toStringMethod.invoke(c));
Community
  • 1
  • 1
Matthew Fontana
  • 3,790
  • 2
  • 30
  • 50
  • It's not an inner class, so your link does not apply. – user207421 Oct 07 '15 at 20:48
  • ProductValueClass is the private inner class of FiscalReport. What is is that you are trying to access? I updated my answer with sample code for accessing the methods of ProductValueClass – Matthew Fontana Oct 07 '15 at 20:55
  • I just tried your way but it seems it cannot find the method. (no such method exception). even doing some alteration – logger Oct 07 '15 at 21:39
  • You have to change "wantedMethod" to your desired method name. You will also have to change the invoke call to hand the proper parameters to the method. – Matthew Fontana Oct 07 '15 at 22:36
  • It's static. Ergo it isn't inner. [Can't be both](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3). It is a static nested class. Your link is about inner classes, and specifically about how to supply the outer instance, which isn't necessary for static nested classes. The code you've now posted has the same problem. – user207421 Oct 08 '15 at 02:32
  • Hi matt i did changed wantedMethod to toString it still says method not found. The static class is giving the problem I think EJP is right. – logger Oct 08 '15 at 13:19
  • Ah just realized you had a static inner class. Ok added a new code segment for you. @EJP thanks for pointing that out completely missed the static modifier when I posted my example – Matthew Fontana Oct 09 '15 at 12:09
  • Note: you'll likely need the entire package name when using classForName: Class.forName("com.mypackage.FiscalReport$ProductValueClass"); Replace "com.mypackage" with whatever your package name for the given class is – AgentKnopf Mar 25 '22 at 08:28