我在使用Class.forName()实例化类时遇到问题。 起初,我试图通过仅使用类名创建类,但它继续抛出" ClassNotFoundError"。所以,我添加了包名,但我的格式是包$ className。 E.g:
`Class<?> cls = Class.forName("GreenhouseControls$ThermostatNight"); //` This Works.
我读取了需要从文件中实例化的类名。创建类后,我使用控制器类中的 addEvent()函数添加事件。
不幸的是,当我尝试让构造函数实例化类时,我得到了一个&#34; NoSuchMethodError&#34;。我不知道为什么?我想知道它是否是不允许我获得子类构造函数的抽象类?
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();
}
}
}
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();
}
}
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);
}
}
}
答案 0 :(得分:1)
你不能像你想要的那样直接创建一个内部类。您只能创建GreenhouseControls类型的对象。
答案 1 :(得分:0)
您必须将Long.TYPE
传递给getDeclaredConstructor
,以便查找ThermostatNight(long)
。目前,它正在寻找一个名为ThermostatNight()
的声明构造函数。
cls = Class.forName("GreenhouseControls$ThermostatNight");
clsCon = cls.getDeclaredConstructor(Long.TYPE);