Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using reflection in Java

I need some help with reflection, since I can't make my code work the way I want to.

I have the following:

nrThreads = Utilities.getNumberOfThreads(filePath, propertiesFile);
testName = Utilities.getTestName(filePath, propertiesFile);  
System.out.println(Utilities.nowDate());
System.out.println("Inserting...");

switch (testName)
{
case "InsertAndCommit":
      final InsertAndCommit[] threads = new InsertAndCommit[nrThreads];
      for (int i = 0; i < nrThreads; i++) {
        threads[i] = new InsertAndCommit();
        threads[i].start();
      }                         
      break;            
case "CommitAfterAllInserts":
      final CommitAfterAllInserts[] threads1 = new CommitAfterAllInserts[nrThreads];
      for (int i = 0; i < nrThreads; i++) {
        threads1[i] = new CommitAfterAllInserts();
        threads1[i].start();
      }
      break;
      default: break;
}

As you can see, I'm repeating code inside this switch/case. I know I can do that piece of code using reflection but I can't seem to get it right.

I've done the following:

 Class<?> clazz = Class.forName(testName);
 Constructor<?> ctor = clazz.getConstructor(String.class);
 final Object[] obj = (Object[]) ctor.newInstance(); //this line isn't right, I need to declare the "threads" array (equivalent to: final InsertAndCommit[] threads = new InsertAndCommit[nrThreads];)

            for (int i = 0; i < nrThreads; i++) {
                //In this line I need to declare a new "generic constructor" with reflection (equivalent to threads[i] = new InsertAndCommit();) 
                threads[i].start();
            }

I've been reading a lot about reflection and I can't seem to get this right, can you please help me?

like image 698
SaintLike Avatar asked Mar 18 '23 15:03

SaintLike


1 Answers

In this line I need to declare a new "generic constructor" with reflection (equivalent to threads[i] = new InsertAndCommit();)

If you use generics, you do not have to do that through a reflection proper, in the sense that you do not need to work with the constructor object explicitly (although Class.newInstance() and Array.newInstance() methods are part of the Java reflection API).

Since you have Class<T>, and because both classes have parameterless constructors, you can call clazz.newInstance() to create a new object, like this:

public <T extends Thread> T[] makeArray(Class<T> clazz, int n) throws Exception {
    T[] res = (T[]) Array.newInstance(clazz, n);
    for (int i = 0 ; i < n ; i++) {
        res[i] = clazz.newInstance();
        res[i].start();
    }
    return res;
}

Demo.

like image 171
Sergey Kalinichenko Avatar answered Mar 28 '23 08:03

Sergey Kalinichenko