无法使用Class.forName()实例化类

时间:2015-12-11 21:10:12

标签: java class reflection constructor

我在使用Class.forName()实例化类时遇到问题。 起初,我试图通过仅使用类名创建类,但它继续抛出" ClassNotFoundError"。所以,我添加了包名,但我的格式是包$ className。 E.g:

`Class<?> cls = Class.forName("GreenhouseControls$ThermostatNight"); //` This Works.

我读取了需要从文件中实例化的类名。创建类后,我使用控制器类中的 addEvent()函数添加事件。

不幸的是,当我尝试让构造函数实例化类时,我得到了一个&#34; NoSuchMethodError&#34;。我不知道为什么?我想知道它是否是不允许我获得子类构造函数的抽象类?

GreenhouseControls.java

import java.io.*;
import java.lang.reflect.*;
import java.lang.Long;
import java.util.*;
import java.util.regex.*;
import tme3.*;

public class GreenhouseControls extends Controller{


    public class ThermostatNight extends Event {

      public ThermostatNight(long delayTime) {
        super(delayTime);
      }
      public void action() {
        // Put hardware control code here.
        thermostat = "Night";
      }
      public String toString() {
        return "Thermostat on night setting";
      }
    }



   public class Restart extends Event {
     public Restart(long delayTime, String filename) {
       super(delayTime);
       eventsFile = filename;
     }

     public void action()  {
       File f = new File(eventsFile);
       try{
         Scanner scan = new Scanner(f);
         Pattern class_name = Pattern.compile("(?<==)(.*)(?=,time)");
         Pattern time1 = Pattern.compile("(?<=time=)(.*)(?=,*)");
         Pattern rings_time = Pattern.compile("(?<=time=)(.*)(?=,)");
         Pattern rings = Pattern.compile("(?<=rings=)(.*)");



         while(scan.hasNextLine()){
            String event_name;
            long l;
            int r = 0;
            Class<?> cls;
            Constructor<?> clsCon;
            event_name = scan.findInLine(class_name)

            try{ 
               String check = scan.findInLine(rings_time);
               check.getClass();
               l = Long.valueOf(check).longValue();
               r = Integer.valueOf(scan.findInLine(rings)).intValue();

            }catch(NullPointerException e){ l = Long.valueOf(scan.findInLine(time1)).longValue(); }

            System.out.println("event_name: " + event_name + " Time: " + l + " Rings: " + r);

           cls = Class.forName("GreenhouseControls$ThermostatNight");

           clsCon = cls.getDeclaredConstructor(); // This Code throws and error because apparently there is no constructor

           if (scan.hasNextLine())
                scan.nextLine();     


         }
      }catch(Exception e) { System.out.println(e); }
    //addEvent(new ThermostatNight(0));
   }   
  }




    public static void main(String[] args) {
      try {
        String option = args[0];
        String filename = args[1];

        if ( !(option.equals("-f")) && !(option.equals("-d")) ) {
          System.out.println("Invalid option");
          printUsage();
        }

        GreenhouseControls gc = new GreenhouseControls();

        if (option.equals("-f"))  {
          gc.addEvent(gc.new Restart(0,filename));
        }

        gc.run();
      }
      catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Invalid number of parameters");
         printUsage();
      }
   }    
}

Event.java

package tme3;

import java.io.*;

public abstract class Event {
  private long eventTime;
  protected final long delayTime;

  public Event(){ delayTime = 0;}
  public Event(long delayTime) {
    this.delayTime = delayTime;
    start();
  }
 public void start() { // Allows restarting
   eventTime = System.currentTimeMillis() + delayTime;
 }
 public boolean ready() {
  return System.currentTimeMillis() >= eventTime;
 }
 public abstract void action();
 }  
}

Controller.java

public class Controller {
    // A class from java.util to hold Event objects:
    private List<Event> eventList = new ArrayList<Event>();
    public void addEvent(Event c) { eventList.add(c); }

    public void run() {
        while(eventList.size() > 0)
            // Make a copy so you're not modifying the list
            // while you're selecting the elements in it:
        for(Event e : new ArrayList<Event>(eventList))
            if(e.ready()) {
            System.out.println(e);
            e.action();
            eventList.remove(e);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

你不能像你想要的那样直接创建一个内部类。您只能创建GreenhouseControls类型的对象。

答案 1 :(得分:0)

您必须将Long.TYPE传递给getDeclaredConstructor,以便查找ThermostatNight(long)。目前,它正在寻找一个名为ThermostatNight()的声明构造函数。

cls = Class.forName("GreenhouseControls$ThermostatNight");
clsCon = cls.getDeclaredConstructor(Long.TYPE);