This was a first stab, but good catches on the NPE and the "[]" and "[" cases. I suppose a quick null/syntax check at the beginning would help.
As far as your optimization goes, I was not aware that the endsWith() operations were so expensive. I think the endsWith() version of the code is much more readable/maintainable, but yours might be faster. I don't know that speed is an extremely important requirement for this code, though. I just forgot to change the append()/'+' statement to chained append() calls. Anyway, thanks for the tips. -----Original Message----- From: Henning P. Schmiedehausen [mailto:[EMAIL PROTECTED] Sent: Tuesday, September 06, 2005 3:30 AM To: [email protected] Subject: Re: [lang] enhanced version of Class.forName "James Carman" <[EMAIL PROTECTED]> writes: >I would say that this is something that would be very useful. We did >something similar in HiveMind. I can imagine an implementation like: I always wondered over the obsession with startsWith() and endsWith() in string-related commons code. These operations are hugely expensive, especially with long strings to check! They are implemented using a loop and char compares. I very much prefer using charAt and length() for this; both are constant time operations. Same goes to the mixture of StringBuffer operations and '+'. Finally append()'ing a char is (at least in the Sun 1.4.x JSDK) more effective than append()'ing a String. Your implementation also throws NPE for className == null BTW. There is also the pathological case of ClassUtils.enhancedForName("[]"). Currently this throws CNF for class '['. How about this: --- cut --- private static Map typeMap = new HashMap(); private static Map abbreviationMap = new HashMap(); static { typeMap.put( "int", Integer.TYPE ); typeMap.put( "boolean", Boolean.TYPE ); typeMap.put( "float", Float.TYPE ); typeMap.put( "long", Long.TYPE ); typeMap.put( "short", Short.TYPE ); typeMap.put( "byte", Byte.TYPE ); typeMap.put( "double", Double.TYPE ); typeMap.put( "char", Character.TYPE ); abbreviationMap.put( "int", "I" ); abbreviationMap.put( "boolean", "Z" ); abbreviationMap.put( "float", "F" ); abbreviationMap.put( "long", "J" ); abbreviationMap.put( "short", "S" ); abbreviationMap.put( "byte", "B" ); abbreviationMap.put( "double", "D" ); abbreviationMap.put( "char", "C" ); } public static Class enhancedForName(String className) throws ClassNotFoundException { Class clazz = null; if (className != null) { clazz = typeMap.get(className); if (clazz == null) { int nameLen = className.length(); StringBuffer actualNameBuffer = new StringBuffer(); boolean foundArray = false; while(namelen > 2 && className.charAt(nameLen - 2) == '[' && className.charAt(nameLen - 1) == ']') { actualNameBuffer.append('['); nameLen -= 2; foundArray = true; } if (!foundArray) { clazz = Class.forName(className); } else { final String abbreviation = (String) abbreviationMap.get(className); if (abbreviation != null) { actualNameBuffer.append(abbreviation); } else { actualNameBuffer.append('L') .append(className) .append(';'); } clazz = Class.forName(actualNameBuffer.toString()); } } } return clazz; } --- cut --- Best regards Henning >public static Class enhancedForName( String className ) throws >ClassNotFoundException >{ > Class clazz = ( Class )typeMap.get( className ); > if( clazz == null ) > { > if( className.endsWith( "[]" ) ) > { > final StringBuffer actualNameBuffer = new StringBuffer(); > while( className.endsWith( "[]" ) ) > { > className = className.substring( 0, className.length() - 2 ); > actualNameBuffer.append( "[" ); > } > final String abbreviation = ( String )abbreviationMap.get( className >); > if( abbreviation != null ) > { > actualNameBuffer.append( abbreviation ); > } > else > { > actualNameBuffer.append( "L" + className + ";" ); > } > clazz = Class.forName( actualNameBuffer.toString() ); > } > else > { > clazz = Class.forName( className ); > } > } > return clazz; >} >-----Original Message----- >From: Thomas Dudziak [mailto:[EMAIL PROTECTED] >Sent: Monday, September 05, 2005 5:05 PM >To: Jakarta Commons Developers List >Subject: [lang] enhanced version of Class.forName >Hi folks, >I had this problem that I needed to create class objects for things >like "int" and "boolean", eg. the type specification that you would >use for a variable declaration or method parameter. >Since the normal Class.forName does not handle this really well, and >commons-lang does not provide such a function (please correct me if >I'm wrong here), I implemented it myself. >Now I wonder, would this be useful enhancement to ClassUtils ? If so, >I could provide a patch in BugZilla. >regards, >Tom >--------------------------------------------------------------------- >To unsubscribe, e-mail: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] >--------------------------------------------------------------------- >To unsubscribe, e-mail: [EMAIL PROTECTED] >For additional commands, e-mail: [EMAIL PROTECTED] -- Dipl.-Inf. (Univ.) Henning P. Schmiedehausen INTERMETA GmbH [EMAIL PROTECTED] +49 9131 50 654 0 http://www.intermeta.de/ RedHat Certified Engineer -- Jakarta Turbine Development -- hero for hire Linux, Java, perl, Solaris -- Consulting, Training, Development 4 - 8 - 15 - 16 - 23 - 42 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
