Java Forum / General / May 2005
Static factory method doesn't work -- non-static does!
Matthias Kaeppler - 22 May 2005 17:08 GMT Howdy,
I have a strange problem:
I want to implement a factory class, which has a static creation method taking an enum type which defines what type will be created. The problem is, as soon as I /do/ make this method static, the program behaves very strange, in that calls on the returned object are never executed.
Here's some code for illustration:
class Factory {
enum Type { TYPE_1, TYPE_2 }
public static Product createProduct( Type t ) { switch( t ) { case( TYPE_1 ) return new Type1Product(); case( TYPE_2 ) return new Type2Product(); } } }
Type1Product and Type2Product extend Product. Now I somewhere pass the reference to the newly created object to some other object's ctor:
Foo obj = new Foo( Factory.createProduct( Factory.Type.TYPE_1 ) );
Inside obj, all calls on the object returned by the factory method fail, in that they are never executed! However, if I make the factory method non-static, and instantiate the whole Factory class first, then everything works just fine!
I can't even remotely imagine what is causing this, can you? Any help greatly appreciated.
Cheers, Matthias
Matthias Kaeppler - 22 May 2005 17:11 GMT > public static Product createProduct( Type t ) { > switch( t ) { [quoted text clipped - 3 lines] > } > } Erm, please ignore the bad syntax in the switch statement... :D Of course I have it right here.
Vincent Vollers - 22 May 2005 19:07 GMT Well, I dont know what you are doing exactly... but I wrote a small test program, and it works perfectly:
the following code produces, as expected:
getNum in ProductTypeOne 1 getNum in ProductTypeTwo 2
=========================== abstract class Product { protected int num;
abstract public int getNum(); }
class ProductTypeOne extends Product { public ProductTypeOne() { num = 1; }
public int getNum() { // TODO Auto-generated method stub System.out.println("getNum in ProductTypeOne"); return num; } }
class ProductTypeTwo extends Product { public ProductTypeTwo() { num = 2; }
public int getNum() { // TODO Auto-generated method stub System.out.println("getNum in ProductTypeTwo"); return num; } }
class TestContainer { private Product product;
public TestContainer(Product p) { this.product = p; System.out.println(p.getNum()); } }
class TestFactory { enum Type { TEST1, TEST2 }
public static Product generateProduct(Type t) { switch(t) { case(TEST1): return new ProductTypeOne(); case(TEST2): default: return new ProductTypeTwo(); } } }
public class TestProgram {
public TestProgram() { new TestContainer(TestFactory.generateProduct(TestFactory.Type.TEST1)); new TestContainer(TestFactory.generateProduct(TestFactory.Type.TEST2)); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new TestProgram(); }
} ===========================
Ross Bamford - 23 May 2005 02:56 GMT > Howdy, > [quoted text clipped - 5 lines] > behaves very strange, in that calls on the returned object are never > executed. Sorry, your problem /is/ strange - works here as expected. However, while playing around with it I came up with this, which I've not seen anywhere before but has probably already been done...? It might help, or it might not...
Imagine an Enum type:
// ----- enum AbstractClassType { FIRST_CLASS (FirstClass.class), SECOND_CLASS (SecondClass.class); // ... etc
Class<? extends AbstractClass> classType; ClassType(Class<? extends AbstractClass> theClass) { classType = theClass; } public AbstractClass instantiate() throws InvocationTargetException { try { return classType.newInstance(); } catch (Exception e) { throw(new InvocationTargetException(e)); } } } // -----
And then imagine a base-class / factory:
// ----- abstract class AbstractClass { public static AbstractClass getInstance(ClassType classType) throws InvocationTargetException { return classType.instantiate(); } public abstract Object someMethod(); // ... etc. } // -----
Cut out the middleman, so to speak. Of course you use it simply:
AbstractClass mine = AbstractClass.getInstance(AbstractClassType.FIRST_CLASS);
or whatever.
?
 Signature [Ross A. Bamford] [ross AT the.website.domain] Roscopeco Open Tech ++ Open Source + Java + Apache + CMF http://www.roscopec0.f9.co.uk/ + info@the.website.domain
John C. Bollinger - 23 May 2005 15:07 GMT > I want to implement a factory class, which has a static creation method > taking an enum type which defines what type will be created. > The problem is, as soon as I /do/ make this method static, the program > behaves very strange, in that calls on the returned object are never > executed. How about you post an example of what you're trying to do that _doesn't_ work. We can point out errors that you may be making in that case, but when we only have an example of some similar thing that does work, we can only speculate about what mistake you may have made in converting it.
 Signature John Bollinger jobollin@indiana.edu
Andrew Thompson - 23 May 2005 15:13 GMT > How about you post an example of what you're trying to do that _doesn't_ > work. A sterling idea John. For more on that concept.. <http://www.physci.org/codes/sscce.jsp>
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Thomas G. Marshall - 23 May 2005 21:14 GMT Andrew Thompson coughed up:
>> How about you post an example of what you're trying to do that >> _doesn't_ work. > > A sterling idea John. For more on that concept.. > http://www.physci.org/codes/sscce.jsp Andrew, you should put a counter on that page. I'd like to see how many times it's been visited.
 Signature "Realtor" and "realty" are pronounced "reel'-tor" and "reel'-tee", *not* "reel'-a-tor" and "reel'-i-tee" !!!! If you pronounce them when the extra syllable, you will sound like a complete idiot.
Andrew Thompson - 24 May 2005 01:12 GMT > Andrew Thompson coughed up: >> [quoted text clipped - 5 lines] > > Andrew, you should put a counter on that page. I have considered using counters at one time or another, but resisted (thus far) for two reasons. 1) They are inherently inaccurate (with caching + 100 other factors) 2) They are considered (in web design circles) to mark a page as made by an 'enthusiastic amateur'.
> ..I'd like to see how many times it's been visited. OK.. Just checked the PhySci.org server stats for April 2005.
In the list of 'Top 30 of 1059 Total URLs' recorded as visited, the SSCCE document comes in at 27th with 867 hits.
Thoughts, ..comments?
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Ross Bamford - 24 May 2005 02:03 GMT > > ..I'd like to see how many times it's been visited. > [quoted text clipped - 4 lines] > > Thoughts, ..comments? If it's not the posters reading it, then who is?
"I have this problem in some code that kind of goes... IF this THEN do this ..."
>8-|
 Signature [Ross A. Bamford] [ross AT the.website.domain] Roscopeco Open Tech ++ Open Source + Java + Apache + CMF http://www.roscopec0.f9.co.uk/ + info@the.website.domain
Andrew Thompson - 24 May 2005 02:26 GMT (T.G.M.)
>>> ..I'd like to see how many times it's been visited. >> >> OK.. Just checked the PhySci.org server stats for April 2005. >> >> In the list of 'Top 30 of 1059 Total URLs' recorded as visited, >> the SSCCE document comes in at 27th with 867 hits. ...
> If it's not the posters reading it, then who is? Aaahh! The first signs of why you should treat such numbers with extreme caution. What does 'reading' mean? It is certainly a subset of 'hits'..
The figure of 867 -hits- includes every time the page was called from the server, including the times .. - I myself checked the exact wording (of some part of it) prior to posting the link in reponse to a question. - The client was a search engine spider. - Visitors clicked the link and then thought, 'No - this isn't what I was after!' and left the page. - Visitors read part of the page but got bored, called away, had power failure.. - Visitors that read the entire page but failed to understand it, or it's deeper message.
So, in the end, these numbers amount to "lies, damned lies, ..and statistics!" ;-)
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Thomas G. Marshall - 24 May 2005 03:55 GMT Andrew Thompson coughed up:
> (T.G.M.) >>>> ..I'd like to see how many times it's been visited. [quoted text clipped - 9 lines] > with extreme caution. What does 'reading' mean? It is certainly > a subset of 'hits'.. Not necesarily. You can have more readings than hits if someone leaves the page up on a monitor and walks away screaming "you gotta read this penthouse forum story!"
> The figure of 867 -hits- includes every time the page was called from > the server, including the times .. [quoted text clipped - 10 lines] > So, in the end, these numbers amount to > "lies, damned lies, ..and statistics!" ;-)
 Signature Everythinginlifeisrealative.Apingpongballseemssmalluntilsomeoneramsitupyournose.
Andrew Thompson - 24 May 2005 05:05 GMT (A.T.)
>> Aaahh! The first signs of why you should treat such numbers >> with extreme caution. What does 'reading' mean? It is certainly [quoted text clipped - 3 lines] > page up on a monitor and walks away screaming "you gotta read this penthouse > forum story!" LOL - sure! But I do not think that happens regularly with the SSCCE page, it does not generate -that- level of enthusiasm.
And I just couldn't resist this..
"Of course, I only read Penthouse for the articles - I browse the site with 'images off'.."
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
hiwa - 24 May 2005 09:35 GMT A ratio at a beginners' forum: When I refer twenty poeple to the SSCCE page, one among them post an SSCCE compliant example code of good quality. Other nineteen keep eternal silence thereafter.
Andrew Thompson - 24 May 2005 11:42 GMT > A ratio at a beginners' forum: > When I refer twenty poeple to the SSCCE page, one among them post an SSCCE > compliant example code of good quality. Other nineteen keep eternal silence > thereafter. So 95% gain a 'debugging tool' powerful enough to enable them to solve their -own- code problems? Way cool!
[ ;-) ]
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Thomas G. Marshall - 24 May 2005 13:41 GMT Andrew Thompson coughed up:
>> A ratio at a beginners' forum: >> When I refer twenty poeple to the SSCCE page, one among them post an [quoted text clipped - 5 lines] > > [ ;-) ] I've *often* wondered if there wasn't a way for a pluggin (or somesuch) to take an example from a post and run it.
Now, it would be fraught with peril, but I also had this concept.
An application that takes a potentially large part of a post broken down using some formalism or other:
----[gurgle.spit.Splat.java]---- (code here) ----[END: gurgle.spit.Splat.java]---
----[gurgle.hack.Lougy.java]--- (etc.) ----[END (etc)
So you do a potentially massive (but hopefully small) cut and paste into this application's window, and it separates it into files and directories, and runs the thing.
Presumably on the front end, the same application would allow you to specify a package and compile + running options, and combine it all into a CnP-able string of text to plop into your message.
Just for examples, etc.
Of course, you'd have to be careful some @#$%wad didn't put in something to erase your HD...
 Signature Doesn't /anyone/ know where I can find a credit card company that emails me the minute something is charged to my account?
Thomas G. Marshall - 24 May 2005 13:41 GMT Thomas G. Marshall coughed up:
> Andrew Thompson coughed up: >> [quoted text clipped - 36 lines] > Of course, you'd have to be careful some @#$%wad didn't put in > something to erase your HD... Note that what I certainly would *not* advocate is having all this hidden by base64....
 Signature Doesn't /anyone/ know where I can find a credit card company that emails me the minute something is charged to my account?
Andrew Thompson - 24 May 2005 14:09 GMT > I've *often* wondered if there wasn't a way for a pluggin (or somesuch) to > take an example from a post and run it. I had the same thought. That is part of the reason I encourage the <sscce></sscce> brackets around the ..SSCCE's to help identify them.
[ Which, of course, does not help your wider concept of allowing _multiple_ source files much - since it limits the code to a single .java file. ]
The original (only ever partly formed) idea was to allow import directly into the Java On-Line Compiler at my site (put the message id in a page at the site and a .JSP fetches it from an archive, parsing the content for the source code ), which would then..
> Now, it would be fraught with peril, but I also had this concept. ..launch the application/applet directly out of an *applet*.
Note that an application/applet launched by an unsigned applet in this way - automatically gains the standard applet security sandbox. With that, the security problems are largely solved. OTOH it also means the scope of the code samples would be limited (no File I/O, limits on system properties checks etc.).
I would also look to intervene in the applet context that you hand to any applets launched, to help prevent silly things like the applet opening 2 copies of itself in target "_blank".
I suspect that might cover most ways that code off the net might be tamed, but have vague worries that even that is not enough.
[ ..Maybe it is best I never got around to that project. ;) ]
 Signature Andrew Thompson http://www.PhySci.org/codes/ Web & IT Help http://www.PhySci.org/ Open-source software suite http://www.1point1C.org/ Science & Technology http://www.LensEscapes.com/ Images that escape the mundane
Thomas G. Marshall - 24 May 2005 14:16 GMT Andrew Thompson coughed up:
...[rip]...
> I suspect that might cover most ways that code off the net might > be tamed, but have vague worries that even that is not enough. > > [ ..Maybe it is best I never got around to that project. ;) ] Not sure.
I think the best bet would be simply to eyeball the code sufficiently before handing it off to the CNR(compile-n-runner). The CNR would know /nothing/ about safety, and have no sandbox, save for your own noggin.
*I WOULD HOPE* that the people who are interested in such a CNR in these ng's would know enough to not just cut, paste and hope. :)
 Signature Having a dog that is a purebred does not qualify it for breeding. Dogs need to have several generations of clearances for various illnesses before being bred. If you are breeding dogs without taking care as to the genetic quality of the dog (again, being purebred is *not* enough), you are what is known as a "backyard breeder" and are part of the problem. Most of the congenital problems of present day dogs are traceable directly to backyard breeding. Spay or neuter your pet responsibly, and don't just think that you're somehow the exception and can breed a dog without taking the care described.
Thomas G. Marshall - 24 May 2005 14:21 GMT Thomas G. Marshall coughed up:
> Andrew Thompson coughed up: > [quoted text clipped - 13 lines] > *I WOULD HOPE* that the people who are interested in such a CNR in > these ng's would know enough to not just cut, paste and hope. :) I've not worked with the security manager for years and years, but otherwise I'm assuming that I could sufficiently modify the class loader such that it detects and places an ENORMOUS warning window in your face when certain classes are used. {shrug}
 Signature Having a dog that is a purebred does not qualify it for breeding. Dogs need to have several generations of clearances for various illnesses before being bred. If you are breeding dogs without taking care as to the genetic quality of the dog (again, being purebred is *not* enough), you are what is known as a "backyard breeder" and are part of the problem. Most of the congenital problems of present day dogs are traceable directly to backyard breeding. Spay or neuter your pet responsibly, and don't just think that you're somehow the exception and can breed a dog without taking the care described.
Ross Bamford - 24 May 2005 10:32 GMT > (T.G.M.) > >>> ..I'd like to see how many times it's been visited. [quoted text clipped - 24 lines] > So, in the end, these numbers amount to > "lies, damned lies, ..and statistics!" ;-)
:))
 Signature [Ross A. Bamford] [ross AT the.website.domain] Roscopeco Open Tech ++ Open Source + Java + Apache + CMF http://www.roscopec0.f9.co.uk/ + info@the.website.domain
Matthias Kaeppler - 24 May 2005 07:52 GMT >> I want to implement a factory class, which has a static creation >> method taking an enum type which defines what type will be created. [quoted text clipped - 6 lines] > when we only have an example of some similar thing that does work, we > can only speculate about what mistake you may have made in converting it. Well, apart from the naming, the real code is the same, with the factory method being static.
class VisualizationFactory {
enum DiagramType { LINE_DIAGRAM, BAR_DIAGRAM, COL_DIAGRAM }
public static Diagram createDiagram( DiagramType type ) { switch( type ) { case LINE_DIAGRAM: System.out.println( "Line Diagram requested" ); return new LineDiagram(); default: // the other classes don't yet exist System.out.println( "unexpected" ); break; }
return null; }
}
public abstract class Diagram {
public abstract void paint( Graphics g ); public abstract void foo(); // for testing, it is never actually called, though invoked!
}
import java.awt.*;
public class LineDiagram extends Diagram {
public void paint( Graphics g ) { System.out.println( "painting line diagram" ); }
public void foo() { System.out.println( "foo" ); }
}
public class MainWindow extends JFrame {
public static void main( String[] args ) { // [...] Diagram diagram = VisualizationFactory.createDiagram(VisualizationFactory.DiagramType.LINE_DIAGRAM);
VisualizationFrame intFrame = new DiagramFrame("Viz", diagram );
}
}
The newly created diagram is passed to a DiagramFrame, which is a JInternalFrame and supposed to draw diagrams. Now inside this DiagramFrame's paint() method:
class DiagramFrame extends VisualizationFrame {
public DiagramFrame( String title, Diagram diagram ) { super( title ); assert( diagram != null ); this.diagram = diagram; }
public void paint( Graphics g ) { super.paint( g );
//Graphics2D g2d = (Graphics2D) g; //diagram.paint( g ); System.out.println( "frame paint" ); diagram.foo(); }
private Diagram diagram;
}
The program outputs "frame paint" on each window update, but the text I am outputting in foo() is NEVER displayed. It is however displayed as soon as I for example replace the call to the factory's creation method with a normal "new LineDiagram()". Then everything works as expected. It also works when I make the creation method non-static and then instantiate the factory class first.
Odd, isn't it.
Chris Uppal - 24 May 2005 09:35 GMT > Well, apart from the naming, the real code is the same, with the factory > method being static. [quoted text clipped - 5 lines] > The program outputs "frame paint" on each window update, but the text I > am outputting in foo() is NEVER displayed. Works fine for me (once I'd added a dummy VisualizationFrame class, the necessary imports, and added a call to initFrame.show() in main() so that the window was actually displayed and its paint() method called).
Output looks like: Line Diagram requeste frame paint foo frame paint foo frame paint foo frame paint foo ...
-- chris
John McGrath - 24 May 2005 09:52 GMT > > How about you post an example of what you're trying to do that > > doesn't work.
> public class MainWindow extends JFrame { > [quoted text clipped - 7 lines] > } > }
> The program outputs "frame paint" on each window update There are quite a few problems with this code:
1) It is missing imports, so it will not compile as is. 2) It contains references to a VisualizationFrame class that is not included. 3) The only main() method just constructs a Diagram and a DiagramFrame. It does not show the frame, so the program terminates when the main() method returns. 4) The code consists of multiple source files,
The following article should help you to produce a more useful example:
http://www.physci.org/codes/sscce.jsp
 Signature Regards,
John McGrath
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 ...
|
|
|