1

I have a Forum class with some subclasses, and I store the subclass name as a String field on a database along all other fields. When I retrieve the object, I want it to be an instance of the same class it was. I could do a lot of if-else statements to find which subclass constructor to call, but it wouldn't be easily extensible.

I have found this solution, but it feels somehow dirty:

    public static Forum createForum(int forumId, String kind) {
         try {
           Class cls = Class.forName("forum."+kind);
           Constructor ct = cls.getConstructor(Integer.TYPE, String.class);
           Object retobj = ct.newInstance(forumId, kind);
           return (Forum) retobj;
         }
         catch (Throwable e) {
            System.err.println(e);
         }
         return null;
    }

Is there any better solution?

Thanks.

3 Answers3

1

I could do a lot of if-else statements to find which subclass constructor to call, but it wouldn't be easily extensible.

One alternative is to create a "factory object" interface for your Forum classes, and then populate a map with factory instances to create each of the subclass.

public interface ForumFactory {
    public Forum createForum(String arg);
}

public class FooForumFactory implements ForumFactory {
    public Forum createForum(String arg) { return new FooForum(arg); }
}

Map<String, ForumFactory> factories = new HashMap<String, ForumFactory>();
factories.put("foo", new FooForumFactory());
factories.put("bar", new BarForumFactory());

...

// Create an instance ...
Forum forum = factories.get(forumType).createForum(forumName);

Things would be more difficult if different subclass constructors required different arguments. But that would also be problematic for your reflective solution.

In the long term, using an ORM (like Hibernate) is likely to give a more elegant solution.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

I think what you're looking for is Object Serialization

(That page is a little advertising heavy, but it has some good info. Googling "java object serialization" will return lots of info)

The Oracle tutorial is here: http://java.sun.com/developer/technicalArticles/Programming/serialization/

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • I thought of that too, but it's not necessarily appropriate for a SQL database, because it would interfere with either normalisation or queryability. (Either you duplicate the data, or it's not possible to query it.) – Robin Green Apr 18 '11 at 22:26
  • Depends ... he could just be going for persistence. You could also implement a serialization that stores it in the DB just as he's doing now (not efficient, but convenient). After that you get into the whole ORM thing with Hibernate, etc ... but it's good to know about serialization. – Brian Roach Apr 18 '11 at 22:33
0

Yes, there is an alternative - Object-Relational Mapping (ORM), which does this for you - and much more besides. ORM frameworks for Java include Hibernate and DataNucleus.

Robin Green
  • 32,079
  • 16
  • 104
  • 187