From: Robert Klemme on 10 Jul 2010 08:17 On 10.07.2010 02:54, markspace wrote: > Lew wrote: > >> try >> { >> // ClassCastException caught so this is safe >> @SuppressWarnings( "unchecked" ) >> Class <Authenticator> clazz = >> (Class <Authenticator>) Class.forName( name ); >> >> authenticator = clazz.newInstance(); >> } > > > The following doesn't generate any warning messages and doesn't require > a @SuppressWarnings annotation. It's also a tad shorter. It will throw > ClassCastException if the type loaded isn't right, but that could be > caught too. I'm not sure it's better, but it is an alternative. > > try > { > Class<?> c = Class.forName( "test" ); > SomeType s = (SomeType) c.newInstance(); > > } catch( InstantiationException ex ) { ... // etc. This is even better because you don't even need a cast: public static Authenticator create1(String className) throws CreationException { try { final Class<? extends Authenticator> cl = Class.forName(className).asSubclass(Authenticator.class); return cl.newInstance(); } catch (ClassNotFoundException e) { throw new CreationException("Class not found: " + className, e); } catch (InstantiationException e) { throw new CreationException("Could not create instance: " + className, e); } catch (IllegalAccessException e) { throw new CreationException("Operation not permitted", e); } } You can even pack it in one line and it doesn't look too ugly: public static Authenticator create2(String className) throws CreationException { try { return Class.forName(className).asSubclass(Authenticator.class).newInstance(); } catch (ClassNotFoundException e) { throw new CreationException("Class not found: " + className, e); } catch (InstantiationException e) { throw new CreationException("Could not create instance: " + className, e); } catch (IllegalAccessException e) { throw new CreationException("Operation not permitted", e); } } Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: markspace on 10 Jul 2010 11:15 Robert Klemme wrote: > > This is even better because you don't even need a cast: > final Class<? extends Authenticator> cl = > Class.forName(className).asSubclass(Authenticator.class); Interesting. Although "asSubclass(Class<?>)" is a cast and the documentation even says "Casts this Class object to represent a subclass of...." It will throw ClassCastException if the named class is not a type of Authenticator, which should be caught, imo, because you probably want to provide a better error mechanism that just halting. Definitely more than one way to do it, I agree.
From: Daniel Pitts on 12 Jul 2010 18:43 On 7/9/2010 6:49 PM, Arne Vajh�j wrote: > On 09-07-2010 20:13, Arne Vajh�j wrote: >> On 09-07-2010 19:07, Simon Brooke wrote: >>> OK, here's a problem which many people must have encountered, and there >>> must be a 'best practice' solution. >>> >>> I have a thing which is configurable by plugging other things into it. >>> Obviously the other things I plug in must conform to specific >>> interfaces, >>> but what thing I actually plug in is determined at run-time by reading >>> the name of the plugin class from a configuration file. An example (in >>> Java 1.4) is as follows: >>> >>> 1 String v = config.getValueAsString( "authenticator_class"); >>> 2 >>> 3 if (v != null) { >>> 4 Class authenticatorClass; >>> 5 >>> 6 try { >>> 7 authenticatorClass = Class.forName( v); >>> 8 } catch (ClassNotFoundException c) { >>> 9 throw new InitialisationException( >>> 10 "Could not find class [" + v >>> 11 + "]", c); >>> 12 } >>> 13 >>> 14 try { >>> 15 authenticator = >>> 16 (Authenticator) authenticatorClass >>> 17 .newInstance(); >>> 18 } catch (ClassCastException e) { >>> 19 throw new InitialisationException( >>> 20 "Not a valid authenticator class", e); >>> 21 } catch (InstantiationException f) { >>> 12 throw new InitialisationException( >>> 23 "Could not instantiate authenticator", f); >>> 24 } >>> 25 } >>> >>> Obviously one can vacuously 'bring this up to date' by changing line >>> 4 to >>> >>> 4 Class<?> authenticatorClass; >>> >>> but I feel that the right thing to do must surely be to use >>> >>> 4 Class<Authenticator> authenticatorClass; >>> 5 >>> 6 try { >>> 7 authenticatorClass = >>> (Class<Authenticator>) Class.forName( v); >>> 8 } catch (Exception e) { >>> >>> then if the class specified did not inherit from Authenticator a >>> ClassCastException would be caught at line 8, and the second try/catch >>> block might become redundant. However, if I do that, Java 1.6 gives me a >>> warning at line 7: >>> >>> 'Type safety: Unchecked cast from Class<capture#1-of ?> to >>> Class<Authenticator>' >>> >>> Eclipse offers to fix this by adding an @SuppressWarnings clause, but >>> I'm >>> not sure I want to suppress warnings... >>> >>> What is the preferred pattern in Java 1.5/1.6, and why? >> >> Have you tried: >> >> authenticatorClass = Class<Authenticator>.forName( v); >> >> ? > > I just did myself. > > It does not compile. forName returns a Class<?> only, you can not ask it to do otherwise. You might be able to do: Class.forName(v).asSubclass(Authenticator.class); -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Christian Kaufhold on 13 Jul 2010 17:55 markspace <nospam(a)nowhere.com> wrote: > Lew wrote: > >> try >> { >> // ClassCastException caught so this is safe >> @SuppressWarnings( "unchecked" ) >> Class <Authenticator> clazz = >> (Class <Authenticator>) Class.forName( name ); >> >> authenticator = clazz.newInstance(); >> } > > > The following doesn't generate any warning messages and doesn't require > a @SuppressWarnings annotation. It's also a tad shorter. It will throw > ClassCastException if the type loaded isn't right, but that could be > caught too. I'm not sure it's better, but it is an alternative. > > try > { > Class<?> c = Class.forName( "test" ); > SomeType s = (SomeType) c.newInstance(); Do never use Class.newInstance(), it will pass through /any/ Throwable that the actual code throws (it is actually one way to throw a checked exception that is not declared). Instead use the explicit no-argument Constructor. Strictly speaking, if a reflectively invoked method throws InterruptedException (wrapped in the InvocationTargetException), one should also interrupt the current Thread (or pass the InterruptedException on), as otherwise the interruption is swallowed.
First
|
Prev
|
Pages: 1 2 Prev: Generics: instantiating an object from a class name inconfiguration Next: Documentation hiding |