I see, interesting!

So Class.newInstance can throw, say, an SQLException even though the signature 
does not declare that exception. 

So if you have fine-grained exception handling (separate catch blocks for 
InstantiationException,  IllegalAccessException, SecurityException etc) then 
you might might not catch that SQLException. 

I guess I've never run into this because I always use a single (catch Exception 
ex) block, and if reflection failed (for any reason) then I either fall back to 
plan B or just fail. 

So I guess it doesn't make much difference in our case. 

But I did learn something new today, thanks! :-)

Remko

Sent from my iPhone

> On 2014/04/17, at 8:00, Matt Sicker <[email protected]> wrote:
> 
> From the docs for Class.newInstance:
> 
> Note that this method propagates any exception thrown by the nullary 
> constructor, including a checked exception. Use of this method effectively 
> bypasses the compile-time exception checking that would otherwise be 
> performed by the compiler. The Constructor.newInstance method avoids this 
> problem by wrapping any exception thrown by the constructor in a (checked) 
> InvocationTargetException.
> 
> 
>> On 16 April 2014 17:40, Remko Popma <[email protected]> wrote:
>> Out of interest, what is the advantage of calling
>> clazz.getConstructor().newInstance();
>> vs
>> clazz.newInstance(); ?
>> 
>> Until now all the code I've seen simply uses newInstance unless the 
>> constructor needs parameters. 
>> And it is shorter. :-) 
>> So just wondering if I missed something...
>> 
>> 
>> 
>>> On Tue, Apr 15, 2014 at 4:03 PM, <[email protected]> wrote:
>>> Author: mattsicker
>>> Date: Tue Apr 15 07:03:55 2014
>>> New Revision: 1587455
>>> 
>>> URL: http://svn.apache.org/r1587455
>>> Log:
>>> Add fallback to Class.newInstance.
>>> 
>>>   - In some scenarios, if a class doesn't have a constructor defined, 
>>> Class.getConstructor() will fail, but Class.newInstance() won't fail. Not 
>>> sure on the logic behind that one, Java.
>>> 
>>> Modified:
>>>     
>>> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java
>>> 
>>> Modified: 
>>> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java
>>> URL: 
>>> http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java?rev=1587455&r1=1587454&r2=1587455&view=diff
>>> ==============================================================================
>>> --- 
>>> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java
>>>  (original)
>>> +++ 
>>> logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/helpers/Loader.java
>>>  Tue Apr 15 07:03:55 2014
>>> @@ -21,6 +21,7 @@ import java.lang.ClassCastException;
>>>  import java.lang.reflect.InvocationTargetException;
>>>  import java.net.URL;
>>> 
>>> +import org.apache.logging.log4j.Level;
>>>  import org.apache.logging.log4j.Logger;
>>>  import org.apache.logging.log4j.status.StatusLogger;
>>>  import org.apache.logging.log4j.util.PropertiesUtil;
>>> @@ -248,7 +249,7 @@ public final class Loader {
>>>              // using the TCCL should work the same as the default 
>>> ClassLoader (i.e., init or not)
>>>              return Class.forName(className, true, getTCL());
>>>          } catch (final Throwable e) {
>>> -            LOGGER.catching(e);
>>> +            LOGGER.catching(Level.DEBUG, e);
>>>              LOGGER.trace("TCCL didn't work. Trying Class.forName({}).", 
>>> className);
>>>              return loadClassWithDefaultClassLoader(className);
>>>          }
>>> @@ -283,7 +284,7 @@ public final class Loader {
>>>          try {
>>>              return Class.forName(className, true, 
>>> ClassLoader.getSystemClassLoader());
>>>          } catch (final Throwable t) {
>>> -            LOGGER.catching(t);
>>> +            LOGGER.catching(Level.DEBUG, t);
>>>              LOGGER.trace("Couldn't use SystemClassLoader. Trying 
>>> Class.forName({}).", className);
>>>              return Class.forName(className);
>>>          }
>>> @@ -306,7 +307,13 @@ public final class Loader {
>>>                     InstantiationException,
>>>                     NoSuchMethodException,
>>>                     InvocationTargetException {
>>> -        return loadClass(className).getConstructor().newInstance();
>>> +        final Class<?> clazz = loadClass(className);
>>> +        try {
>>> +            return clazz.getConstructor().newInstance();
>>> +        } catch (final NoSuchMethodException e) {
>>> +            //noinspection ClassNewInstance
>>> +            return clazz.newInstance();
>>> +        }
>>>      }
>>> 
>>>      /**
>>> @@ -342,7 +349,7 @@ public final class Loader {
>>>          try {
>>>              final Class<?> clazz = loadClass(className);
>>>              return clazz != null;
>>> -        } catch (final Exception ignored) {
>>> +        } catch (final Throwable ignored) {
>>>              return false;
>>>          }
>>>      }
> 
> 
> 
> -- 
> Matt Sicker <[email protected]>

Reply via email to