catch
clause.The
ReflectiveOperationException
is a checked exception class extended by older (available prior to 1.7) exception classes ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, and NoSuchMethodException. There is an obvious advantage to having a checked exception that is a parent to all of these pre-existing checked exceptions that could be thrown by reflection operations: it is much easier to "catch" a single exception or declare a "throws" clause for a single exception rather than for all of the checked reflection exceptions.The new JDK 7 feature supporting handling of multiple exceptions with a single catch block might also be used in this situation, but I like this general reflection operation exception approach. The following code examples demonstrate all three approaches (catching each individual checked exception, catching the new checked parent exception
ReflectiveOperationException
, and using the new JDK 7 multiple exception catching mechanism).Traditional Individual Reflection Exception Handling
/**
* Instantiate an instance of Person using the provided parameters and invoke
* its toString() method with code using the traditional catching of
* individual checked exceptions related to the various Java reflection calls.
*
* @param newLastName Last name of Person instance to be instantiated.
* @param newFirstName First name of Person instance to be instantiated.
* @param newAge Age of Person instance to be instantiated.
*/
public void instantiatePersonReflectivelyTraditionally(
final String newLastName, final String newFirstName, final int newAge)
{
final String className = "dustin.examples.Person";
final String methodName = "toString";
try
{
final Class clazz = Class.forName(className);
final Class[] ctorParams = {String.class, String.class, Integer.TYPE};
final Constructor ctor = clazz.getConstructor(ctorParams);
final Person person = (Person) ctor.newInstance(newLastName, newFirstName, newAge);
final Method toStringMethod = clazz.getDeclaredMethod(methodName);
out.println(toStringMethod.invoke(person));
}
catch (ClassNotFoundException cnfEx)
{
err.println("Unable to instantiate class " + className + ": " + cnfEx);
}
catch (NoSuchMethodException nsmEx)
{
err.println("No method " + className + "." + methodName + ": " + nsmEx);
}
catch (IllegalAccessException illAccEx)
{
err.println(
"IllegalAccessException encountered invoking " + className + "."
+ methodName + ": " + illAccEx);
}
catch (InvocationTargetException invokeTargetEx)
{
err.println(
"InvocationTargetException encountered invoking " + className + "."
+ methodName + ": " + invokeTargetEx);
}
catch (InstantiationException ctorEx)
{
err.println("Unable to instantiate " + className + ": " + ctorEx);
}
}
Java 7: Catching Single ReflectiveOperationException
/**
* Instantiate an instance of Person using the provided parameters and invoke
* its toString() method with code that only needs to capture the single
* exception ReflectiveOperationException available with Java 7.
*
* @param newLastName Last name of Person instance to be instantiated.
* @param newFirstName First name of Person instance to be instantiated.
* @param newAge Age of Person instance to be instantiated.
*/
public void instantiatePersonReflectivelyJava7ReflectiveOperationException(
final String newLastName, final String newFirstName, final int newAge)
{
final String className = "dustin.examples.Person";
final String methodName = "toString";
try
{
final Class clazz = Class.forName(className);
final Class[] ctorParams = {String.class, String.class, Integer.TYPE};
final Constructor ctor = clazz.getConstructor(ctorParams);
final Person person = (Person) ctor.newInstance(newLastName, newFirstName, newAge);
final Method toStringMethod = clazz.getDeclaredMethod(methodName);
out.println(toStringMethod.invoke(person));
}
catch (ReflectiveOperationException reflectOpEx) // single exception!
{
err.println(
"Reflection error trying to invoke " + className + "."
+ methodName + ": " + reflectOpEx);
}
}
Java 7: Catching Multiple Reflection Exceptions with Single Catch
/**
* Instantiate an instance of Person using the provided parameters and invoke
* its toString() method with code using the Java 7 language feature allowing
* multiple exceptions to be explicitly specified for capture in a single
* catch block.
*
* @param newLastName Last name of Person instance to be instantiated.
* @param newFirstName First name of Person instance to be instantiated.
* @param newAge Age of Person instance to be instantiated.
*/
public void instantiatePersonReflectivelyJava7MultiCatch(
final String newLastName, final String newFirstName, final int newAge)
{
final String className = "dustin.examples.Person";
final String methodName = "toString";
try
{
final Class clazz = Class.forName(className);
final Class[] ctorParams = {String.class, String.class, Integer.TYPE};
final Constructor ctor = clazz.getConstructor(ctorParams);
final Person person = (Person) ctor.newInstance(newLastName, newFirstName, newAge);
final Method toStringMethod = clazz.getDeclaredMethod(methodName);
out.println(toStringMethod.invoke(person));
}
catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException reflectionEx)
{
err.println(
"Reflection error trying to invoke " + className + "."
+ methodName + ": " + reflectionEx);
}
}
I didn't show it here because it's considered "bad form," but another option would have been to catch generic Exception as the singly caught exception (similar to example catching only ReflectiveOperationException but much broader). I generally prefer to catch an exception as specific to the situation as possible. Assuming the exception handling is the same for all of the relevant exceptions, I prefer not to list them each individually. This makes the approach of catching the new
ReflectiveOperationException
or the new Java 7 multiple exception catching mechanism most appealing. I slightly prefer catching ReflectiveOperationException
when appropriate (reflection), but the multiple exception catching mechanism is a more general tactic for situations where no convenient parent exception exists.Conclusion
JDK 7 provides two new and better mechanisms for handling exceptions commonly thrown when using Java reflection. The new ability to catch multiple exceptions with a single catch clause is generally useful for catching multiple exceptions that are to be handled the same way. The availability of ReflectiveOperationException in Java 7 is a specific exception parent class that can be caught to handle all its child reflection exception classes in a single catch.
Không có nhận xét nào:
Đăng nhận xét