Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 8 of 8

Thread: How do you use class.forname?

  1. #1
    Junior Member
    Join Date
    Mar 2010
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default How do you use class.forname?

    I'm working on a project that needs to utilize external classes. A few years ago I used Class.forName to do this and I remember using an interface. However, I can't remember how this worked. Can someone tell me if they see any problems with the code below:

    //Main.java
    package directlink;
     
    public class Main {
     
        Main() {
            try {
                Class c = Class.forName("directlink.classes.Dfile");
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            }
        }
     
        public static void main(String[] args) {
            new Main();
        }
    }

    //Command.java
    package directlink.classes;
     
    import java.util.Vector;
     
    abstract class Command implements Commandinterface {
        Vector<String> options;
     
        Command() {
            this.options = new Vector<String>(10, 10);
        }
     
        public void setOptions(Vector<String>options) {
            this.options = options;
        }
    }

    //Commandinterface.java
    package directlink.classes;
     
    import java.util.Vector;
     
    public interface Commandinterface {
        public void setOptions(Vector<String> name);
        public Vector<String[]> getActions();
        public void runAction(String action);
    }

    //Dfile.java
    package directlink.classes;
    import java.util.Vector;
     
    public class Dfile extends Command implements Commandinterface {
        public Vector<String[]> getActions() {
            Vector<String[]> actions = new Vector<String[]>(5, 5);
            String[] command = new String[2];
            command[0] = "copy";
            command[1] = "from to";
            actions.add(command);
     
            command = new String[2];
            command[0] = "delete";
            command[1] = "from";
            actions.add(command);
     
            return actions;
        }
     
        public void runAction(String action) {
            if (action.equals("copy")) {
                //This is just to make sure Class.forName is working this is not a real command
                System.out.println("Copying file from to");
            }
        }
    }

    and this loads without error. However if I try to use:

    c.runAction("copy");

    I get the error:

    Exception in thread "main" java.lang.RuntimeException: Uncompilable source code
    at directlink.Main.<init>(Main.java:12)
    at directlink.Main.main(Main.java:19)
    Java Result: 1
    Last edited by Json; May 17th, 2010 at 06:52 AM.

  2. #2
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: How do you use class.forname?

    Hi, the problem you have encountered is the fact that when you call Class.forName it wont actually return you an instance of that class but it will return the actual class if that makes sense. You will then have to create a new instance of the object before you can call any methods on it.

    final Class c = Class.forName("directlink.classes.Dfile")
    final Dfile dfile = (Dfile) c.newInstance();
    dfile.runAction("copy");

    That should work better for you.

    // Json

  3. #3
    Junior Member
    Join Date
    Mar 2010
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How do you use class.forname?

    I changed my code to:

    package directlink;
     
    public class Main {
     
        Main() throws InstantiationException, IllegalAccessException {
            try {
                final Class c = Class.forName("directlink.classes.Dfile");
                final Dfile dfile = (Dfile)c.newInstance();
                dfile.runAction("copy");
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            }
        }
     
        public static void main(String[] args) throws InstantiationException, IllegalAccessException {
            new Main();
        }
    }

    and I'm getting an Uncompilable source code - cannot find symbol error. I understand what you're saying (I think). However, doesn't your code eliminate the ability for dynamic classes. Right after we use forname the next line assumes you know the name of the class that will be instantiated. Doesn't this eliminate the ability to add new classes later.
    Last edited by Json; May 17th, 2010 at 02:12 PM.

  4. #4
    Junior Member
    Join Date
    May 2010
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How do you use class.forname?

    exactly speaking Class.forName()will load the class binary to memory, but it could't new a instance automatically, so after the line Class.forName("directlink.classes.Dfile") you need to do c.newInstance()

  5. #5
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: How do you use class.forname?

    What symbol can you not find, could you please show me the stack trace?

    Also, I think I know what you mean, usually when I've used reflection to instantiate classes I know that these classes will implement an interface or extend an abstract class so I will be able to cast it. Other than that when you instantiate this objects using reflection there must be a reason for you to do so. Figure out what the reason is and tell me what you want to be able to achieve and I'll let you know if that's possibly or not and maybe even how it can be done.

    I've also used reflection to load a class dynamically which was located in a jar file and the class would be annotated so I could easily see if that was the class I wanted. I've also come across the scenario where the jar file will have an xml file or something like it with some properties telling me what class I should instantiate.

    Anywho, like I said, find out why you're instantiating these classes in the first place.

    // Json

  6. #6
    Forum old-timer
    Join Date
    Nov 2008
    Location
    Faversham, Kent, UK
    Posts
    472
    My Mood
    Mellow
    Thanks
    4
    Thanked 58 Times in 54 Posts

    Default Re: How do you use class.forname?

    Quote Originally Posted by mydarkpassenger View Post
    ... However, doesn't your code eliminate the ability for dynamic classes. Right after we use forname the next line assumes you know the name of the class that will be instantiated. Doesn't this eliminate the ability to add new classes later.
    This aspect of Reflection should be used polymorphically - that is, you know what methods you will be calling on the external class (otherwise you couldn't do anything with it!), but you don't know the details of how the class implements them - different classes will do different things when you call those methods. So what is done is to cast the newly instantiated class object to an interface that the class implements. This way, at a certain point in your code, you can load, instantiate, and call methods on any class that implements the particular interface you want to use. You can add new classes later as long as they implement the interface, and you can load them by reading their names from a config/properties file, or a database, or whatever.

  7. #7
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: How do you use class.forname?

    Another thing you might want to make sure you understand is the difference between the two forName methods.

    public static Class<?> forName(String className) throws ClassNotFoundException
     
    public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException

    Take note of the initialize argument, if set to true, it will initialize the class (run any static blocks and set up static members), if false it will leave these alone.

    // Json

  8. #8
    Junior Member
    Join Date
    May 2010
    Posts
    7
    Thanks
    0
    Thanked 1 Time in 1 Post

    Default Re: How do you use class.forname?

    I tried this way and it is running.I hope it may help you.
    public class Main {
     
        Main() {
            try {
                Class c = Class.forName("testing.Dfile");
                c.getMethod("runAction", java.lang.String.class).invoke(c.newInstance(),"copy");
     
            } catch (ClassNotFoundException x) {
                x.printStackTrace();
            } catch (SecurityException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (NoSuchMethodException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InvocationTargetException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InstantiationException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
        }
     
        public static void main(String[] args) {
            new Main();
        }
    }
    Last edited by Json; May 20th, 2010 at 02:30 AM. Reason: Please use code tags.

Similar Threads

  1. any ways to run a class from another class?
    By javanub:( in forum Java Theory & Questions
    Replies: 3
    Last Post: May 9th, 2010, 06:57 AM
  2. Replies: 0
    Last Post: April 11th, 2010, 08:56 AM
  3. problem with data access when a class call another class
    By ea09530 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: April 4th, 2010, 05:20 PM
  4. Accessing a method of one class in another class
    By Sai in forum What's Wrong With My Code?
    Replies: 6
    Last Post: March 23rd, 2010, 04:06 PM
  5. how to load a class and type cast to that class?
    By chinni in forum Object Oriented Programming
    Replies: 2
    Last Post: November 9th, 2009, 10:18 AM