This discussion is archived
8 Replies Latest reply: Apr 20, 2010 1:21 AM by 843798 RSS

getConstructor( )

843798 Newbie
Currently Being Moderated
Hi,
I have multiple classes which all extend from the same super class.
Each of the classes must take an int argument, however I need to be able to call these classes on the fly and I can't seem to figure out how to do this.

I can call each one of the classes seperatly like this:
LightOff lo = new LightOff(300);
but they all extend of the class Event,
Here is a sample of the code:

LightOn class
public class LightOff extends Event {
    public LightOff(long delayTime) { super(delayTime); }
    public void action() {
      //Enter hardware control code here
    }
    public String toString() { return "Light is off"; }
  }
Event class
public abstract class Event implements Runnable {
  private long delay;
  //protected final long delayTime;
  public Event(long delayTime) {
    delay = delayTime;
    run();
  }
  
  public void run() {
       try{
            TimeUnit.MILLISECONDS.sleep(delay);            
       }catch(InterruptedException e){
            System.out.println(e + "Interrupted!");
       }
       action();
       System.out.println(this);
  }
  
  public abstract void action();
} ///:~
And a call from main:
public static void main(String args[]){
   String event = "LightOff";
   int time = 300;
   Class eventClass = Class.forName(event);
   Constructor ctor = eventClass.getConstructor(Integer.class);
   //Right here I don't know what to call to get the LightOff class to start
}
  • 1. Re: getConstructor( )
    EJP Guru
    Currently Being Moderated
    Each of the classes must take an int argument
    Each of the classes must take a long argument, to agree with the constructor for Event.
    Class eventClass = Class.forName(event);
    Class<? extends Event> eventClass = (Class<? extends Event>)Class.forName(event);
    Constructor ctor = eventClass.getConstructor(Integer.class);
    Constructor<? extends Event> ctor = eventClass.getConstructor(long.class);
    //Right here I don't know what to call to get the LightOff class to start
    long delay = 5555L; // or whatever
    Event event = ctor.newInstance(delay);
  • 2. Re: getConstructor( )
    baftos Expert
    Currently Being Moderated
    ejp wrote:
     Constructor<? extends Event> ctor = eventClass.getConstructor(long.class);
    This should probably be
     Constructor<? extends Event> ctor = eventClass.getConstructor(Long.TYPE);
  • 3. Re: getConstructor( )
    EJP Guru
    Currently Being Moderated
    Thanks, both work.
  • 4. Re: getConstructor( )
    baftos Expert
    Currently Being Moderated
    Thanks and sorry for correcting what I thought was a typo.
    I did not know this syntax is valid (since when? autoboxing?).
    Now I know.
  • 5. Re: getConstructor( )
    EJP Guru
    Currently Being Moderated
    Since 1.1 as far as I know. I was certainly using in the 1990s.
  • 6. Re: getConstructor( )
    843798 Newbie
    Currently Being Moderated
    Hmm,
    This was working great, but now I am having a weird issue.

    I moved the call to each Event object into it's own method and now when I compile the program I get this:
    >
    Note: GreenhouseControls.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    >

    So if I recompile with -Xlint I get this:

    >
    GreenhouseControls.java:159: warning: [unchecked] unchecked cast
    found : java.lang.Class<capture#532 of ?>
    required: java.lang.Class<? extends tme3.Event>
    Class<? extends Event> eventClass = (Class<? extends Event>)Class.forName(className);
    >
    There is an arrow pointing to the className in brackets on the last line.
    className is a String for the class in which I am going to call, ex. LightOff
  • 7. Re: getConstructor( )
    EJP Guru
    Currently Being Moderated
    That's because Class.forName() returns a Class<?>. Not much you can do about this except @SuppressWarnings("unchecked").
  • 8. Re: getConstructor( )
    843798 Newbie
    Currently Being Moderated
    There's a way to make the check explicit:
    Class<? extends Event> eventClass = Class.forName(className).asSubclass(Event.class);
    This way the check is actually done at that line (in the asSubclass() method) and you can avoid the ugly @SupressWarnings.