1

I have a method that accepts an Event like this:

   addEvent(Event event);

The Event constructor accepts a long type like this:

   Event(long delayTime);

So, I can explicitly define an argument into addEvent like this:

   addEvent(new ThermostatNight(2000)); //ThermostatNight=Event and 2000=delayTime

However, I want to extract Event and delayTime values from a text file, hold them in an array and then pass them into an addEvent() construct as I loop through the arrays.

I have been able to solve half of the problem. I used Long.parseLong to convert the String delayTime values from the text file into a long type and pass it into the Event construct like this:

   addEvent(ThermostatNight(y)); // Where y = the converted long type delayTime 

Now I just need to figure out how to convert the String event type from the text file, for example ThermostatNight, into an Event type so that the addEvent method will accept it like this:

   addEvent(x(y)) // x = Event value; y = long value

Would Class.forName work for this? I have tried to use it on the events held in the array but I get a ClassNotFoundException. Here is a snippet of code showing what I am trying to do:

for(String e2 : array2){
    try{
        Class<?> className = Class.forName(e2);
        System.out.println(className);          
    } catch (ClassNotFoundException e) {
        System.out.println("Class not found");
    }
}

2 Answers 2

1

Another solution without reflection (because of many reasons to avoid reflection) is to use the factory pattern for this problem.

Your factory class could look like this (assuming Event is an interface or abstract class for ThermostatNight and AnotherEventClass):

public class EventFactory {
    public static Event createSpecificEvent(String eventName, long delayTime) {
        Event event;

        switch (eventName) {  // String switch-case statements since Java 7
        case "ThermostatNight":
            event = new ThermostatNight(delayTime);
            break;
        case "AnotherEventClass":
            event = new AnotherEventClass(delayTime);
            break;
        default:
            throw new IllegalArgumentException("Unknown event type.");
        }

        return event;
    }
}

And called like this:

long y = 1234;

for (String e2 : array2) {
    Event event = EventFactory.createSpecificEvent(e2, y);
    System.out.println(event.getClass().getName());
}
Sign up to request clarification or add additional context in comments.

1 Comment

Should there be a break between each case?
1

Yes, Class.forName should work here.

1) Here e2 should be like "package1.package2.ThermostatNight" i.e. the fully
qualified class name. Also, that class should be available to this code at
runtime for loading (so the class must be present in compiled form, you know,
in a jar file or in class dir which is on the classpath).

2) After loading the class, you need to find and call the proper
constructor (the one with long argument) via reflection.
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/package-summary.html
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Constructor.html
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html

3) What is the declared type of the parameter of addEvent?
If it is ThermostatNight (and not Object), then you will need to
cast the object you created (from your dynamically loaded class) to
ThermostatNight which means you will need to use ThermostatNight
at compile-time and so then you should not have problem with 1) as
the presence or absence of this class with become visible
at compile-time.

2 Comments

When you say e2 should be like "package1.package2.ThermostatNight" do you mean I have to explicitly type that in? There are many text files and the event types will change so I wanted the Class.forName to grab the event type for me... I hope that makes sense. I am new to Java and programming.
OK, if you have events and they can be of different types then your program needs to know them. No, you don't need to hardcode their full class names in the code, but the code needs to load these full class names from some place e.g. from a property file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.