Prev: setJPEGEncodeParam method not found in JPEGImageEncoder jdk 1.5 and jdk 1.6
Next: HYDROCODONE SIDE EFFECTS INFORMATION
From: Tom Anderson on 18 Nov 2009 13:12 Hi chaps, We have a class which does some setup in a static block that needs to happen early in the lifecycle of the app (this is a dubious design, but there you go - it's largely forced on us from without). Thus, it needs to get loaded early. We have an initialiser class which runs at a suitable time, so that's where we'll load the class. What's the best way to do this? Before i came to it, the code looked like: void initialise() { Class.forName("com.example.Foo"); } I didn't like that, because it's using a string constant where it could be using something strongly typed, and so not getting enabling refactoring and inspection in the IDE. I had a bit of a debate with my pair, and we changed it to: void initialise() { Class.forName(Foo.class.getName()); } Which works, solves the problem, and is clearly bonkers. What's a good idiom? One option would be to call a no-op method on the class literal: void initialise() { Foo.class.getName(); } But that's a bit hackish too. I could just store it in a local: void initialise() { Class foo = Foo.class; } Since i actually have several classes, i could put them in an array: void initialise() { Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class}; } Am i right in thinking that all of these will force loading of Foo? Does anyone have any other idioms? How about any opinions on which idiom is best, or at least most idiomatic? Thanks, tom -- A hypothesis or theory is clear, decisive, and positive, but it is believed by no one but the man who created it. Experimental findings, on the other hand, are messy, inexact things, which are believed by everyone except the man who did that work. -- Harlow Shapley
From: markspace on 18 Nov 2009 13:32 Tom Anderson wrote: > void initialise() { > Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class}; > } > > Am i right in thinking that all of these will force loading of Foo? Well, rule #1 is "if it ain't broke don't fix it", so this whole enterprise is dubious to me. However, I don't see why these classes won't be loaded in any of the examples you presented. The only issue I see is that an optimizer may decide that the objects are "not used" and optimize them away. That is, actually remove the statements referencing the classes. Thus you might want to actually do something with the classes: void initialise() { Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class}; Logger logger = Logger.getLogger( "x" ); for( Class c : loadedClasses ) { logger.config( "Loaded class: "+c.getName() ); } } Replace "x" with the class name in which initialise() is declared. This may also be bonkers, but it's a safe kind of bonkers, I think.
From: Peter Duniho on 18 Nov 2009 13:36 Tom Anderson wrote: > [...] > Am i right in thinking that all of these will force loading of Foo? I think so. But I haven't checked the spec to make sure. > Does > anyone have any other idioms? How about any opinions on which idiom is > best, or at least most idiomatic? I find the question ironic. :) The fact is, you've got some clearly non-idiomatic scenario, where for some reason your code has managed to become dependent on the initialization of a class that it does not in fact refer to in the process of being dependent on it. Given that violation of a very fundamental assumption one normally could make in a Java program, asking for an idiomatic solution to the violation seems sort of silly to me. Your code is already broken; any work-around is destined to be non-idiomatic. :) Pete
From: Tom Anderson on 18 Nov 2009 14:01 On Wed, 18 Nov 2009, markspace wrote: > Tom Anderson wrote: > >> void initialise() { >> Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class}; >> } >> >> Am i right in thinking that all of these will force loading of Foo? > > Well, rule #1 is "if it ain't broke don't fix it", so this whole > enterprise is dubious to me. Son, you may wish to look into getting a new rule provider. If it ain't broke but it's smelly, it's going to break, so fix it now before it does. > However, I don't see why these classes won't be loaded in any of the > examples you presented. The only issue I see is that an optimizer may > decide that the objects are "not used" and optimize them away. That is, > actually remove the statements referencing the classes. Since class loading is side-effectual, i don't think an optimiser is free to do that. Although i admit i'm a bit shaky about the rules on this. > Thus you might want to actually do something with the classes: > > void initialise() { > Class[] loadedClasses = new Class[] {Foo.class, Bar.class, Baz.class}; > > Logger logger = Logger.getLogger( "x" ); > for( Class c : loadedClasses ) { > logger.config( "Loaded class: "+c.getName() ); > } > } > > Replace "x" with the class name in which initialise() is declared. > > This may also be bonkers, but it's a safe kind of bonkers, I think. It at least makes it look like something useful is being done, which is what matters! I also considered: void initialise() { loadClass(Foo.class); } void loadClass(Class cl) { // do nothing! } ! tom -- A hypothesis or theory is clear, decisive, and positive, but it is believed by no one but the man who created it. Experimental findings, on the other hand, are messy, inexact things, which are believed by everyone except the man who did that work. -- Harlow Shapley
From: Tom Anderson on 18 Nov 2009 14:06 On Wed, 18 Nov 2009, Peter Duniho wrote: > Tom Anderson wrote: >> [...] >> Am i right in thinking that all of these will force loading of Foo? > > I think so. But I haven't checked the spec to make sure. > >> Does anyone have any other idioms? How about any opinions on which idiom is >> best, or at least most idiomatic? > > I find the question ironic. :) The fact is, you've got some clearly > non-idiomatic scenario, where for some reason your code has managed to become > dependent on the initialization of a class that it does not in fact refer to > in the process of being dependent on it. > > Given that violation of a very fundamental assumption one normally could make > in a Java program, asking for an idiomatic solution to the violation seems > sort of silly to me. Your code is already broken; any work-around is > destined to be non-idiomatic. :) What's really happening is more like this: class FooMangler implements Mangler { static { ManglerRegistry.register("foo", FooMangler.class); } } class ManglingParser extends org.xml.sax.helpers.DefaultHandler { public void startElement (String uri, String localName, String qName, Attributes attrs) throws SAXException { String manglerName = attrs.getValue("mangler"); Mangler mangler = ManglerRegistry.lookup(manglerName); mangler.mangle(qName, attrs); } } The idea is that manglers can take care of registering themselves - as long as they're loaded. This is an old and fairly well-known pattern (at least, not wildly obscure - in terms of birds, about as common as a kingfisher is in England), although i certainly wouldn't say it's a good one, or even a non-dubious one. 'Broken' is a bit too strong, although only a bit. tom -- Osteoclasts = monsters from the DEEP -- Andrew
|
Next
|
Last
Pages: 1 2 3 4 5 6 7 Prev: setJPEGEncodeParam method not found in JPEGImageEncoder jdk 1.5 and jdk 1.6 Next: HYDROCODONE SIDE EFFECTS INFORMATION |