Java Forum / General / November 2005
object factory
Michael Müller - 24 Nov 2005 20:47 GMT All,
I want to launch different visual classes (all derived from JInternalFrame) just by name.
I'm not thinking about a solution with a couple of if statemants like
if (accessName== "Adress"){ frame.add(new Adress("Test")); } else if (accessName== "Order"){ frame.add(new Order("Test")); }
I want to use an object factory to create these classes dynamically - only by using class' name In the docs I found getObjectInstance - this needs an object as argument. :(
I'm searching for something like
obj = createObject(accessName); fram.add(obj);
Do you know any solution? Any help is appreciated.
Michael
NullBock - 24 Nov 2005 20:59 GMT Why do you need an extant method? Roll your own factory class instead:
interface FrameFactory { public JInternalFrame createFrame(String name); }
something along those lines. Then you just need to implement it for the various frames that you want to produce.
Walter Gildersleeve Freiburg, Germany
______________________________________________ http://linkfrog.net URL Shortening Free and easy, small and green
Michael Müller - 26 Nov 2005 10:36 GMT NullBock schrieb am 24.11.2005 21:59:
> Why do you need an extant method? Roll your own factory class instead: > [quoted text clipped - 12 lines] > URL Shortening > Free and easy, small and green Thank you and everybody else for duggestions.
Oliver Wong - 24 Nov 2005 22:43 GMT > All, > [quoted text clipped - 22 lines] > Do you know any solution? > Any help is appreciated. Sounds like you want the class.forName() method, which loads a class with the given name (assuming the ClassLoader can find it). From there, you can use reflection to discover its constructors and then invoke the constructors.
It's generally better, though, to pass in a class object directly, and invoke a constructor on that, than to pass in a String, find the class object, and then invoke a constructor.
- Oliver
Thomas Hawtin - 25 Nov 2005 14:38 GMT > Sounds like you want the class.forName() method, which loads a class > with the given name (assuming the ClassLoader can find it). From there, you > can use reflection to discover its constructors and then invoke the > constructors. Nooooo!!! Don't go around spreading those sort of ideas. Particularly as it leads to the other class method which is utterly broken.
> It's generally better, though, to pass in a class object directly, and > invoke a constructor on that, than to pass in a String, find the class > object, and then invoke a constructor. Or, better still, an abstract factory. Reserve the use of Class to where it is absolutely necessary.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Chris Uppal - 25 Nov 2005 14:48 GMT > > It's generally better, though, to pass in a class object directly, > > and invoke a constructor on that, than to pass in a String, find the > > class object, and then invoke a constructor. > > Or, better still, an abstract factory. Reserve the use of Class to where > it is absolutely necessary. It would be nice if there were a standard interface, java.lang.Factory<X>, which was implemented by java.lang.Class<X>.
-- chris
Thomas Hawtin - 25 Nov 2005 15:16 GMT > It would be nice if there were a standard interface, java.lang.Factory<X>, > which was implemented by java.lang.Class<X>. What would you do with exceptions?
I'd go for a factory interface something along the lines of:
public interface NoArgFactory<PRODUCT, EXC extends Throwable> { PRODUCT create() throws EXC; }
For Class to implement that, I'd require a new exception that wraps some or all of InstantiationException, IllegalAccessException, IllegalArgumentException and InvocationTargetException.
I don't think it's a big thing to require more general code like:
new MyFactory() { public MyProduct create() { return new Fing(); }}
in place of
Fing.class
Although, as ever, I'd like the syntax for anonymous inner classes to be smarter.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Chris Uppal - 26 Nov 2005 11:42 GMT > > It would be nice if there were a standard interface, > > java.lang.Factory<X>, which was implemented by java.lang.Class<X>. > > What would you do with exceptions? Probably just punt and declare Throwable, unless the exception hierarchy is up for re-engineering. Class.newInstance() declares too many checked exceptions.
> public interface NoArgFactory<PRODUCT, EXC extends Throwable> { > PRODUCT create() throws EXC; That's an interesting use of generics. Not something that had (or would have) occurred to me. I presume the compiler will accept it ?
> I don't think it's a big thing to require more general code like: > [quoted text clipped - 3 lines] > > Fing.class Bit difficult to replace uses of Class.forName() in the same way, although one could have a utility function to create adaptors, something like:
static <T> Factory<T> makeFactory(Class<T> cl) { return new Factory ( public T create() throws Throwable { return cl.newInstance(); } ); }
Seems a bit roundabout to me, though. Class objects /are/ factories already, and I'd rather expose that directly as a general purpose abstraction. Either that or deprecate their role as factories completely, which might be cleaner -- java.lang.Class is otherwise a pure class /description/ only (their use for static synchronisation is another wart, of course, but unfortunately that is hard-wired in...)
Pipedreams...
-- chris
Thomas Hawtin - 26 Nov 2005 20:42 GMT >>public interface NoArgFactory<PRODUCT, EXC extends Throwable> { >> PRODUCT create() throws EXC; > > That's an interesting use of generics. Not something that had (or would have) > occurred to me. I presume the compiler will accept it ? Yup. The generic parameter must be declared to extend at least Throwable. With an unchecked cast, you can throw an undeclared checked exception, without so much as Class.newInstance or JNI.
It's slightly annoying that you can only supply a single type for the exception (or a fixed number). No (or fewer) exceptions can be specified by using RuntimeException or Error. Now, if we had union as well as intersection types...
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Chris Uppal - 28 Nov 2005 14:03 GMT > > > public interface NoArgFactory<PRODUCT, EXC extends Throwable> { > > > PRODUCT create() throws EXC; [quoted text clipped - 5 lines] > Throwable. With an unchecked cast, you can throw an undeclared checked > exception, without so much as Class.newInstance or JNI. I take it you mean by casting (say) an object implementing: NoArgFactory<String, IOException> to a: NoArgFactory<String, Error>
That's /very/ nice...
Interestingly, the compiler not only shuts up about the lack of a catch for the checked exception, it's silent about the cast too -- even with -Xlint.
> It's slightly annoying that you can only supply a single type for the > exception (or a fixed number). You'll just have to wait for them to add varadic type parameters to the language. Coming soon to a JSR near you...
-- chris
P.S. It took me a few minutes to see what Thomas was refering to, so here's some sample code for anyone interested:
import java.io.IOException;
interface Maker<C, X extends Throwable> { C make(int n) throws X; }
class Fing {}
class FingMaker implements Maker<Fing, IOException> { public Fing make(int n) throws IOException { if (n < 0) throw new IOException("Oops!"); return new Fing(); } }
public class Test { public static void main(String[] args) { FingMaker m1 = new FingMaker(); Maker<Fing, Error> m2 = (Maker<Fing, Error>)m1; // silent ! m2.make(-1); // silent !!! } }
Thomas Hawtin - 28 Nov 2005 14:32 GMT > I take it you mean by casting (say) an object implementing: > NoArgFactory<String, IOException> [quoted text clipped - 5 lines] > Interestingly, the compiler not only shuts up about the lack of a catch for the > checked exception, it's silent about the cast too -- even with -Xlint. It should give at least an unchecked warning (unless there is a bug in the compiler).
> Maker<Fing, Error> m2 = (Maker<Fing, Error>)m1; // silent ! I get an error. Much the same as if I was casting, say, String to Integer:
Test.java:29: inconvertible types found : FingMaker required: Maker<Fing,java.lang.Error> Maker<Fing, Error> m2 = (Maker<Fing, Error>)m1; // silent ! ^ 1 error
It can be "corrected":
Maker<Fing, Error> m2 = (Maker<Fing, Error>)(Maker)m1; // silent !
Which gives:
Test.java:29: warning: [unchecked] unchecked cast found : Maker required: Maker<Fing,java.lang.Error> Maker<Fing, Error> m2 = (Maker<Fing, Error>)(Maker)m1; // silent ! ^ 1 warning
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Chris Uppal - 28 Nov 2005 15:13 GMT > > Interestingly, the compiler not only shuts up about the lack of a catch > > for the checked exception, it's silent about the cast too -- even with > > -Xlint. > > It should give at least an unchecked warning (unless there is a bug in > the compiler). Indubitably a bug in the compiler.
> > Maker<Fing, Error> m2 = (Maker<Fing, Error>)m1; // silent ! > > I get an error. Much the same as if I was casting, say, String to Integer: For me, the javacs from 1.5.0-b64 and 1.5.0_05-b05 both compile the test code without any complaint (and produce "correct" bytecode). Which version are you using ?
-- chris
Thomas Hawtin - 28 Nov 2005 18:33 GMT > [Chris Uppal wrote:] > [quoted text clipped - 5 lines] > without any complaint (and produce "correct" bytecode). Which version are you > using ? 1.6.0 "rc" b61. I see the same as you with 1.5.0_05 on my old machine (I was waiting for u6 before bothering to put it on the new one). But 1.6 seems to have gained as well as lost bugs. Always the way.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|