I could not agree more on reflection. The management potential of reflection is huge. I really like Stuart Dabbs Halloway's book "Component Development for the Java Platform," which is really reflection based in essence, and love the JMX API. Still, the present problem is not a very good example of the proper use of reflection. Just tossing my three cents in. I wish I had a job where I could work on the development of Java management tools with JMX. Man! That would be a kick! The possibilities are staggering.
At 12:22 PM 9/30/2002 -0700, you wrote: >Comments intermixed. > >On Mon, 30 Sep 2002, John Bindel wrote: > > > Date: Mon, 30 Sep 2002 13:49:22 -0500 > > From: John Bindel <[EMAIL PROTECTED]> > > Reply-To: Struts Users Mailing List <[EMAIL PROTECTED]> > > To: Struts Users Mailing List <[EMAIL PROTECTED]> > > Subject: Re: [OT - Java] How can I do this in Java? > > > > On Mon, Sep 30, 2002 at 12:02:41PM -0500, Jerry Jalenak wrote: > > > > > Yeah, already ran across the exceptions. Right now I'm trying > > > to decide how to handle them since all of this code is actually > > > in a custom Validator routine..... > > > > Good Lord, people, why is reflection anything but the option of > > last resort here? > > > >While I agree with you that using reflection was a poor design choice for >the problem stated here (the patterns should really be loaded from a data >file instead of introspecting from the class), your condemnation of >reflection in general is based on an incorrect definition of the term, and >also outdated behavior related to performance. See below for more. > > > You really do not want to be calling Class.forname(String) unless > > there is some class that cannot be loaded by the compiler. First, > > calling Class.forname is slow, and second, it perversely gets > > rid of the compile-time type-safety that you would have is you > > simply used MyClass.class. > > > >The Class.forName() method is not really reflection -- it is dynamic class >loading. Struts itself uses this to good effect, because it's not >possible to know (at the time ActionServlet is compiled) the names of all >the Action and ActionForm subclasses that *your* application will be >using. > >Further, there is no loss of type safety when using dynamic class loading >in the usual fashion, because you normally cast to the base class you are >looking for. For example, module error checking, this is how Struts >actually loads an Action class instance: > > ClassLoader loader = > Thread.currentThread().getContextClassLoader(); > if (classLoader == null) { > loader = this.getClass().getClassLoader(); > } > Action action = (Action) loader.loadClass(actionClassName); > >Note the cast to an Action, which protects you from type safety problems. > >Of course, using dynamic class loading in the use case being discussed in >this mail thread was totally unnecesary. But please stop casting >aspersions on a very useful feature of the Java language that makes >dynamically extensible applications like Struts possible in the first >place. > > > Reflection is a tool that's useful when you do not know at build > > time the classes with which you will be dealing. It's useful for > > discovery of APIs. Using reflection instead of a lookup table > > is needlessly obtuse and will cause your VM to do all sorts of > > work on which any programmer should not want to be wasting CPU > > cycles. > > > > > > 1. Using reflection here is fragile, especially if it's not wrapped > > within the class that defines your constants. Java is a strongly > > typed language so letting the compiler help you is encouraged. > > > >Since the problem at hand was to access *data*, the best approach would be >to store the patterns externally in a properties file. Then, the data >could be used by multiple classes when it is needed (including the class >in which the format strings are currently embedded). > > > 2. Using reflection is slow. If you still think it's the way you > > want to go, I would strongly recommend limiting the times you > > call Class.forname, etc., such that you do not call it every time > > you validate the zip code. > > > >Firstly, as above, Class.forName() is not reflection. > >Secondly, a subsequent call to Class.forName() for the same class name is >*not* going to load the class bytecodes again; the class loader will >remember that the requested class name has already been loaded, and just >returns you the same instance. > >Thirdly, there is *zero* performance difference (at runtime) between >loading a class via Class.forName() and loading one (for the first time) >with a "new" operator. Why? Because they both end up calling the exact >same loadClass() method -- it's just a question of whether the developer >calls the method explicitly or the bytecodes generated by the compiler >call it for you. > >As for the performance of real life uses of reflection, have you ever >noticed how Struts actually implements the population of your form bean >properties from the request parameters? Yep ... that's right ... every >single call to a property setter is done via reflection. Seems fast >enough to me, especially on a 1.4 JDK where the performance difference >between direct calls and reflected calls is very very small. > > > 3. Using reflection makes you check all sorts of exceptions for > > things that you as the programmer know should not occur, but only > > can be you are circumventing the type checking provided by the > > language. This is a clue that what should be a simple task is > > being made more complex than it needs to be. > > > >In the particular use case at hand, reflection is the wrong technology to >use. However, it makes possible some things that would otherwise be >impossible, or insanely complicated (to do form bean population without >using reflection, Struts would have to examine all your form beans, then >generate a custom Java class to do the auto-population and make sure these >classes were all compiled and included in your webapp -- not something >that can be guaranteed in a portable fashion). > > > 4. I'm not sure what your application is, but using regexp strings > > to validate ZIP codes per state seems like a bad idea. The US > > post office makes new ZIP codes all the time, and unless you are > > getting a list from them every week, the most you may want your > > application to do is warn the user that the application doesn't > > recognize the ZIP code. > > > >It doesn't look like he wanted to check the exact codes, just that the >code is in the correct range for that state. This is a perfectly >reasonable compromise if you cannot afford the time to do the database >lookup, or you don't have the mechanisms to maintain a current list of all >the individual codes in your database. > > > 5. Tell your product managers that validating ZIP codes is not > > something you can do reliably without an often-updated list of > > ZIP codes that you would need to download from the Post Office > > on a regular schedule since your list of regexp string will > > become outdated. > > > > 6. Lookup tables implemented by arrays or HashMaps are orders > > of magnitude faster than the sequence of function calls and system > > calls that you have to do with reflection. > > > > > > I'm sorry I had to write this, but I am befuddled by the lack > > of outcry over using reflection instead of a simple lookup table. > > > >I'm saddened by the fact that you take a case of misuese of a particular >feature and turn it into a diatribe against ever using it. > > > Cheers, > > John > >Craig > > > > > > > > -----Original Message----- > > > > From: Taylor, Jason [mailto:[EMAIL PROTECTED]] > > > > Sent: Monday, September 30, 2002 11:57 AM > > > > To: 'Struts Users Mailing List' > > > > Subject: RE: [OT - Java] How can I do this in Java? > > > > > > > > > > > > good point-- you'd also want to printStackTrace() (if possible) before > > > > rethrowing InvocationTargetException, since it can be > > > > difficult to debug an > > > > ITE otherwise... > > > > > > > > -----Original Message----- > > > > From: Daniel Jaffa [mailto:[EMAIL PROTECTED]] > > > > Sent: Monday, September 30, 2002 9:49 AM > > > > To: Struts Users Mailing List > > > > Subject: Re: [OT - Java] How can I do this in Java? > > > > > > > > > > > > Make sure your code in a proper try and catch. Using > > > > reflection spits out > > > > nasty errors if anything is not right.:( > > > > > > > > ClassCastException > > > > IllegalAccessException > > > > NoSuchMethodException > > > > InvocationTargetException > > > > > > > > Daniel jaffa > > > > ----- Original Message ----- > > > > From: "Jerry Jalenak" <[EMAIL PROTECTED]> > > > > To: "'Struts Users Mailing List'" <[EMAIL PROTECTED]> > > > > Sent: Monday, September 30, 2002 11:46 AM > > > > Subject: RE: [OT - Java] How can I do this in Java? > > > > > > > > > > > > > Jason - Thanks for the code snippet - worked like a charm > > > > first time! I > > > > > tend to get lost in JavaDoc sometimes, so this was a nice > > > > example to have > > > > on > > > > > how to wind my way through to the answer! Thanks again! > > > > > > > > > > John - Thanks for the suggestion on using the HashMap. I'm > > > > going to file > > > > it > > > > > away for now and use Jason's reflection method - but it > > > > never hurts to > > > > have > > > > > a couple of different methods to use on something like this! > > > > > > > > > > Thanks guys! > > > > > > > > > > Jerry > > > > > > > > > > > -----Original Message----- > > > > > > From: Taylor, Jason [mailto:[EMAIL PROTECTED]] > > > > > > Sent: Monday, September 30, 2002 10:28 AM > > > > > > To: 'Struts Users Mailing List' > > > > > > Subject: RE: [OT - Java] How can I do this in Java? > > > > > > > > > > > > > > > > > > I don't happen to have any sample code that does exactly what > > > > > > you're doing, > > > > > > but off the top of my head (with a little help from sun's > > > > > > javadoc) I'd say > > > > > > it's something like: > > > > > > > > > > > > import java.lang.reflect.Field; > > > > > > > > > > > > String stateCode = "AK"; > > > > > > Class constantClass = > > > > > > Class.forName("com.yourdomain.yourapp.Constants"); > > > > > > Field stateField = constantClass.getDeclaredField(stateCode); > > > > > > String stateRegExp = (String) stateField.get(constantClass); > > > > > > System.err.println("regexp for "+stateCode+": "+stateRegExp); > > > > > > > > > > > > I don't really know any more about reflection than you, I > > > > > > just followed the > > > > > > trail from java.lang.Class to java.lang.reflect.Field. Once > > > > > > you've done it > > > > > > once, you see it's no mystery-- you're just doing runtime > > > > compiling. > > > > > > > > > > > > HTH-- This is just how I'd start, as I haven't tested or used > > > > > > this code. If > > > > > > I'm wrong, I'm sure you can figure out what I missed by > > > > > > studying the API > > > > > > docs. If, on the other hand, you don't like reading javadocs > > > > > > and generating > > > > > > your own test cases, LOL! > > > > > > > > > > > > -JT > > > > > > > > > > > > -----Original Message----- > > > > > > From: Jerry Jalenak [mailto:[EMAIL PROTECTED]] > > > > > > Sent: Monday, September 30, 2002 8:05 AM > > > > > > To: 'Struts Users Mailing List' > > > > > > Subject: RE: [OT - Java] How can I do this in Java? > > > > > > > > > > > > > > > > > > Jason, > > > > > > > > > > > > Thanks for the quick reply. I just took at look at the > > > > > > API's, but don't yet > > > > > > understand enough about reflection to know how to > > > > implement it. Just > > > > > > looking at the methods I don't see a way to do what I want - > > > > > > any chance that > > > > > > you'd have some sample code laying about? > > > > > > > > > > > > Jerry > > > > > > > > > > > > > -----Original Message----- > > > > > > > From: Taylor, Jason [mailto:[EMAIL PROTECTED]] > > > > > > > Sent: Monday, September 30, 2002 9:59 AM > > > > > > > To: 'Struts Users Mailing List' > > > > > > > Subject: RE: [OT - Java] How can I do this in Java? > > > > > > > > > > > > > > > > > > > > > sounds like a job for reflection (java.lang.reflect.*;) Have > > > > > > > you looked at > > > > > > > java.lang.Class and java.lang.reflect.Field? > > > > > > > > > > > > > > -----Original Message----- > > > > > > > From: Jerry Jalenak [mailto:[EMAIL PROTECTED]] > > > > > > > Sent: Monday, September 30, 2002 7:50 AM > > > > > > > To: '[EMAIL PROTECTED]' > > > > > > > Subject: [OT - Java] How can I do this in Java? > > > > > > > > > > > > > > > > > > > > > OK - off topic, but Sun's java forum sucks, and there are an > > > > > > > incredible > > > > > > > number of Java guru's on this list, so I thought I'd throw > > > > > > > this out here. > > > > > > > (That and I am using this in a custom validation routine > > > > > > > :-)) Any help > > > > > > > would be GREATLY appreciated! > > > > > > > > > > > > > > Here's the scenario - I've got a series of static constants > > > > > > > that represent > > > > > > > Java regular expressions. These RE's are used to validate > > > > > > > driver license > > > > > > > formats for the 50 states + DC. The strings look like this: > > > > > > > > > > > > > > public static final String AK = "^[0-9]{1,7}$"; > > > > > > > public static final String AL = "^[0-9]{7}$"; > > > > > > > public static final String AR = "^[0-9]{8,9}$"; > > > > > > > public static final String AZ = > > > > > > > "^[0-9ABDY][0-9]{8}$|^[A-Z][0-9]{3,6}$|^[A-Z]{2}[0-9]{3,5}$"; > > > > > > > public static final String CA = "^[A-Z][0-9]{4,7}$"; > > > > > > > public static final String CO = > > > > > > > "^[A-Z][0-9]{1,6}$|^[A-Z]{2}[0-9]{1,6}$|^[0-9]{9}$"; > > > > > > > etc. etc. etc. > > > > > > > > > > > > > > On my form I have a drop-down box of states, and a field for > > > > > > > the license > > > > > > > number. In my custom validator routine, I pick up the value > > > > > > > of the state, > > > > > > > and build a string to represent the constant - i.e. > > > > > > > > > > > > > > private static boolean validateDriversLicenseNumber(String > > > > > > > licenseState, String licenseNumber) > > > > > > > { > > > > > > > String licenseConstant = "Constants." + licenseState; > > > > > > > > > > > > > > I then want to use "licenseConstant" in a Pattern / Match: > > > > > > > > > > > > > > Pattern p = Pattern.compile(licenseConstant, > > > > > > > Pattern.CASE_INSENSITIVE); > > > > > > > Match m = p.matcher(licenseNumber); > > > > > > > return (m.find()); > > > > > > > } > > > > > > > > > > > > > > Obviously the line "String licenseConstant = "Constants." + > > > > > > > licenseState;" > > > > > > > does not give me the value of Constant.<state name>; the > > > > > > > question I have is, > > > > > > > is there a method (or something) that will allow me to build > > > > > > > such a string, > > > > > > > and return the value (i.e. the regular expression)? Or is > > > > > > > there a better > > > > > > > way of doing this? > > > > > > > > > > > > > > TIA! > > > > > > > > > > > > > > Jerry Jalenak > > > > > > > Web Publishing > > > > > > > LabOne, Inc. > > > > > > > 10101 Renner Blvd. > > > > > > > Lenexa, KS 66219 > > > > > > > (913) 577-1496 > > > > > > > [EMAIL PROTECTED] > > > > > > > > > > > > > > > > > > > > > This transmission (and any information attached to it) may be > > > > > > > confidential > > > > > > > and is intended solely for the use of the individual or > > > > > > > entity to which it > > > > > > > is addressed. If you are not the intended recipient or > > > > the person > > > > > > > responsible for delivering the transmission to the intended > > > > > > > recipient, be > > > > > > > advised that you have received this transmission in error and > > > > > > > that any use, > > > > > > > dissemination, forwarding, printing, or copying of this > > > > > > information is > > > > > > > strictly prohibited. If you have received this transmission > > > > > > > in error, please > > > > > > > immediately notify LabOne at (800)388-4675. > > > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > > To unsubscribe, e-mail: > > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > For additional commands, e-mail: > > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > > > > > > > > This transmission (and any information attached to it) may be > > > > > > confidential > > > > > > and is intended solely for the use of the individual or > > > > > > entity to which it > > > > > > is addressed. If you are not the intended recipient or the person > > > > > > responsible for delivering the transmission to the intended > > > > > > recipient, be > > > > > > advised that you have received this transmission in error and > > > > > > that any use, > > > > > > dissemination, forwarding, printing, or copying of this > > > > information is > > > > > > strictly prohibited. If you have received this transmission > > > > > > in error, please > > > > > > immediately notify LabOne at (800)388-4675. > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > > To unsubscribe, e-mail: > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > For additional commands, e-mail: > > > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > > > > > This transmission (and any information attached to it) may > > > > be confidential > > > > and is intended solely for the use of the individual or > > > > entity to which it > > > > is addressed. If you are not the intended recipient or the person > > > > responsible for delivering the transmission to the intended > > > > recipient, be > > > > advised that you have received this transmission in error and > > > > that any use, > > > > dissemination, forwarding, printing, or copying of this information is > > > > strictly prohibited. If you have received this transmission > > > > in error, please > > > > immediately notify LabOne at (800)388-4675. > > > > > > > > > > > > > > > > > > > > -- > > > > > To unsubscribe, e-mail: > > > > <mailto:[EMAIL PROTECTED]> > > > > > For additional commands, e-mail: > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > > > > > > -- > > > > To unsubscribe, e-mail: > > > > <mailto:[EMAIL PROTECTED]> > > > > For additional commands, e-mail: > > > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > This transmission (and any information attached to it) may be > confidential and is intended solely for the use of the individual or > entity to which it is addressed. If you are not the intended recipient or > the person responsible for delivering the transmission to the intended > recipient, be advised that you have received this transmission in error > and that any use, dissemination, forwarding, printing, or copying of this > information is strictly prohibited. If you have received this > transmission in error, please immediately notify LabOne at (800)388-4675. > > > > > > > > > > > > -- > > > To unsubscribe, > e-mail: <mailto:[EMAIL PROTECTED]> > > > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > -- > > end of line > > > > > > -- > > To unsubscribe, > e-mail: <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > > > >-- >To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> >For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>