Java/Reflection/Exception
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
Check whether given exception is compatible with the exceptions declared in a throws clause
import java.lang.reflect.Array;
import java.util.Arrays;
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//Revised from springframework
/**
* Miscellaneous object utility methods. Mainly for internal use within the
* framework; consider Jakarta"s Commons Lang for a more comprehensive suite
* of object utilities.
*
* @author Juergen Hoeller
* @author Keith Donald
* @author Rod Johnson
* @author Rob Harrop
* @author Alex Ruiz
* @since 19.03.2004
* @see org.apache.rumons.lang.ObjectUtils
*/
abstract class ObjectUtils {
private static final int INITIAL_HASH = 7;
private static final int MULTIPLIER = 31;
private static final String EMPTY_STRING = "";
private static final String NULL_STRING = "null";
private static final String ARRAY_START = "{";
private static final String ARRAY_END = "}";
private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
/**
* Check whether the given exception is compatible with the exceptions
* declared in a throws clause.
* @param ex the exception to checked
* @param declaredExceptions the exceptions declared in the throws clause
* @return whether the given exception is compatible
*/
public static boolean isCompatibleWithThrowsClause(Throwable ex, Class[] declaredExceptions) {
if (!isCheckedException(ex)) {
return true;
}
if (declaredExceptions != null) {
for (int i = 0; i < declaredExceptions.length; i++) {
if (declaredExceptions[i].isAssignableFrom(ex.getClass())) {
return true;
}
}
}
return false;
}
/**
* Return whether the given throwable is a checked exception:
* that is, neither a RuntimeException nor an Error.
* @param ex the throwable to check
* @return whether the throwable is a checked exception
* @see java.lang.Exception
* @see java.lang.RuntimeException
* @see java.lang.Error
*/
public static boolean isCheckedException(Throwable ex) {
return !(ex instanceof RuntimeException || ex instanceof Error);
}
}
Get StackTraceElement
//----------------------------------------------------------------------------//
// //
// C l a s s U t i l //
// //
// Copyright (C) Herve Bitteur 2000-2009. All rights reserved. //
// This software is released under the GNU General Public License. //
// Please contact users@audiveris.dev.java.net to report bugs & suggestions. //
//----------------------------------------------------------------------------//
//
/**
* Class <code>ClassUtil</code> provides utilities related to Class handling.
*
* @author Hervé Bitteur
* @version $Id: ClassUtil.java,v 1.3 2009/03/03 19:45:51 hbitteur Exp $
*/
public class ClassUtil
{
//~ Methods ----------------------------------------------------------------
//-----------------//
// getCallingFrame //
//-----------------//
/**
* Infer the calling frame, skipping the given classes if so provided.
* Code was derived from a private method found in the JDK Logger class
*
* @param skippedClasses the classes to skip
* @return the frame found, just before the skipped classes (or just before
* the caller of this method)
*/
public static StackTraceElement getCallingFrame (Class... skippedClasses)
{
// Get the current stack trace.
StackTraceElement[] stack = (new Throwable()).getStackTrace();
// Simple case, no classes to skip, just return the caller of the caller
if (skippedClasses.length == 0) {
return stack[2];
}
// More complex case, return the caller, just before the skipped classes
// First, search back to a method in the skipped classes, if any
int ix;
searchingForSkipped:
for (ix = 0; ix < stack.length; ix++) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
for (Class skipped : skippedClasses) {
if (cname.equals(skipped.getName())) {
break searchingForSkipped;
}
}
}
// Now search for the first frame before the skipped classes
searchingForNonSkipped:
for (; ix < stack.length; ix++) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
for (Class skipped : skippedClasses) {
if (cname.equals(skipped.getName())) {
continue searchingForNonSkipped;
}
}
// We"ve found the relevant frame.
return frame;
}
// We haven"t found a suitable frame
return null;
}
//--------//
// nameOf //
//--------//
/**
* Report the full name of the object class, without the package information
*
* @param obj the object to name
* @return the concatenation of (enclosing) simple names
*/
public static String nameOf (Object obj)
{
StringBuilder sb = new StringBuilder();
for (Class cl = obj.getClass(); cl != null;
cl = cl.getEnclosingClass()) {
if (sb.length() > 0) {
sb.insert(0, "-");
}
sb.insert(0, cl.getSimpleName());
}
return sb.toString();
}
}
Is Checked Exception
import java.lang.reflect.Array;
import java.util.Arrays;
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//Revised from springframework
/**
* Miscellaneous object utility methods. Mainly for internal use within the
* framework; consider Jakarta"s Commons Lang for a more comprehensive suite
* of object utilities.
*
* @author Juergen Hoeller
* @author Keith Donald
* @author Rod Johnson
* @author Rob Harrop
* @author Alex Ruiz
* @since 19.03.2004
* @see org.apache.rumons.lang.ObjectUtils
*/
abstract class ObjectUtils {
private static final int INITIAL_HASH = 7;
private static final int MULTIPLIER = 31;
private static final String EMPTY_STRING = "";
private static final String NULL_STRING = "null";
private static final String ARRAY_START = "{";
private static final String ARRAY_END = "}";
private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
/**
* Return whether the given throwable is a checked exception:
* that is, neither a RuntimeException nor an Error.
* @param ex the throwable to check
* @return whether the throwable is a checked exception
* @see java.lang.Exception
* @see java.lang.RuntimeException
* @see java.lang.Error
*/
public static boolean isCheckedException(Throwable ex) {
return !(ex instanceof RuntimeException || ex instanceof Error);
}
}
Utilities to use Java reflection without all of the checked exceptions
import java.lang.reflect.Array;
import java.lang.reflect.Method;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/**
*
* ReflectUtils is a collection of utilities that allows you to leverage Java
* reflection without all of the checked exceptions (they are converted to
* runtime exceptions or return values). This class was created to get around
* the fact that the classes in java.lang.reflect.* turn every event into an
* exception, which is often cumbersome or inaccurate.
*
* @author Dan Jemiolo (danj)
*
*/
class ReflectUtils {
//
// The class loader used by this class
//
private static final ClassLoader _DEFAULT_CLASS_LOADER;
//
// The class loader used by this class
//
private static ReflectUtilHelper _helper = null;
static {
//
// load the default class loader (we need an instance to do so)
//
ReflectUtils instance = new ReflectUtils();
_DEFAULT_CLASS_LOADER = instance.getClass().getClassLoader();
_helper = null;
}
/**
*
* @param className
* The qualified name of the class to search for.
*
* @return True if the class is in the JVM"s classpath.
*
*/
public static boolean exists(String className) {
if (_helper != null)
return _helper.exists(className);
try {
Class.forName(className);
return true;
}
catch (ClassNotFoundException error) {
return false;
}
}
/**
*
* @param className
* The qualified name of the class to search for.
*
* @param classLoader
* The class loader to use in the class lookup.
*
* @return True if the class is in the JVM"s classpath.
*
*/
public static boolean exists(String className, ClassLoader classLoader) {
try {
classLoader.loadClass(className);
return true;
}
catch (ClassNotFoundException error) {
return false;
}
}
/**
*
* @param theClass
* A "normal", non-array type.
*
* @return The array version of the given type. For example, if you pass
* <em>String.class</em>, you get <em>String[].class</em>. If
* you pass <em>int.class</em>, you get <em>int[].class</em>. If
* the given class is already an array type, it is returned.
*
* @see #getClassFromArrayClass(Class)
*
*/
public static Class getArrayClassFromClass(Class theClass) {
if (theClass.isArray())
return theClass;
return Array.newInstance(theClass, 0).getClass();
}
/**
*
* This method calls getClass(Class, ClassLoader) with this class"
* ClassLoader.
*
* @param className
* The name of the class to load.
*
* @return The Class representing the given class name. A RuntimeException is
* thrown if the class is not found.
*
* @see #exists(String)
*
*/
public static Class getClass(String className) {
if (_helper != null) {
Class clazz = _helper.getClass(className);
if (clazz != null)
return clazz;
}
return getClass(className, _DEFAULT_CLASS_LOADER);
}
/**
*
* @param className
* The name of the class to load.
*
* @param classLoader
* The class loader to use for class lookup.
*
* @return The Class representing the given class name. A RuntimeException is
* thrown if the class is not found.
*
* @see #exists(String)
*
*/
public static Class getClass(String className, ClassLoader classLoader) {
try {
return classLoader.loadClass(className);
}
catch (Throwable error) {
//
// if it failed, try the default loader, if applicable
//
if (_helper != null) {
Class clzz = _helper.getClass(className);
if (clzz != null)
return clzz;
}
if (classLoader != _DEFAULT_CLASS_LOADER) {
try {
return _DEFAULT_CLASS_LOADER.loadClass(className);
}
catch (Throwable error2) {
//
// still failed - ignore this one and throw from the
// original error
//
}
}
Object[] filler = { className };
String message = "JavaClassNotFound";
throw new RuntimeException(message);
}
}
/**
*
* @param arrayClass
* The array version of a given type (<em>YourType[].class</em>)
*
* @return The non-array version of the given type. For example, if you pass
* <em>String[].class</em>, you get <em>String.class</em>. If
* you pass <em>int[].class</em>, you get <em>int.class</em>.
*
* @see #getArrayClassFromClass(Class)
*
*/
public static Class getClassFromArrayClass(Class arrayClass) {
if (arrayClass == null)
throw new NullPointerException("NullClass");
String name = arrayClass.getName();
//
// make sure it"s an array type
//
if (name.charAt(0) != "[") {
Object[] filler = { name };
throw new RuntimeException("NotArrayClass");
}
if (name.charAt(1) == "[") {
Object[] filler = { name };
throw new RuntimeException("NoMultiArrays");
}
//
// the char after the [ signifies the type of the array. these
// values are documented with java.lang.Class.getName()
//
char type = name.charAt(1);
switch (type) {
case "Z":
return boolean.class;
case "B":
return byte.class;
case "C":
return char.class;
case "D":
return double.class;
case "F":
return float.class;
case "I":
return int.class;
case "J":
return long.class;
case "S":
return short.class;
case "L":
return getClass(name.substring(2, name.length() - 1));
default:
Object[] filler = { name, new Character(type) };
String message = "UnsupportedType";
throw new RuntimeException(message);
}
}
public static Method getFirstMethod(Class theClass, String name) {
Method[] methods = theClass.getMethods();
for (int n = 0; n < methods.length; ++n)
if (name.equals(methods[n].getName()))
return methods[n];
return null;
}
/**
*
* @param theClass
*
* @return The full name of the Java package that contains the given class, or
* null if the class is not in a package.
*
*/
public static String getPackageName(Class theClass) {
//
// NOTE: Using the Package would be the easiest way to get this
// data, but the ClassLoader is not required to provide it. Thus,
// we use the more reliable method of parsing the class name.
//
//
// arrays will have the [ as part of their name - no good
//
if (theClass.isArray())
theClass = getClassFromArrayClass(theClass);
return getPackageName(theClass.getName());
}
/**
*
* @param qualifiedName
*
* @return The full name of the Java package that contains the given class, or
* null if the class is not in a package.
*
*/
public static String getPackageName(String qualifiedName) {
int dot = qualifiedName.lastIndexOf(".");
return dot >= 0 ? qualifiedName.substring(0, dot) : null;
}
/**
*
* @param type
*
* @return The unqualified (local) name of the class/interface. If the type is
* an array, the [] characters will be appended.
*
*/
public static String getShortName(Class type) {
if (type.isArray()) {
Class base = getClassFromArrayClass(type);
String name = getShortName(base);
return name + "[]";
}
return getShortName(type.getName());
}
/**
*
* @param qualifiedName
*
* @return The unqualified (local) name.
*
*/
public static String getShortName(String qualifiedName) {
int dot = qualifiedName.lastIndexOf(".");
return qualifiedName.substring(dot + 1);
}
/**
*
* Invokes the Class.newInstance() method on the given Class.
*
* @param theClass
* The type to instantiate.
*
* @return An object of the given type, created with the default constructor.
* A RuntimeException is thrown if the object could not be created.
*
*/
public static Object newInstance(Class theClass) {
try {
return theClass.newInstance();
}
catch (InstantiationException error) {
Object[] filler = { theClass };
String message = "ObjectCreationFailed";
throw new RuntimeException(message);
}
catch (IllegalAccessException error) {
Object[] filler = { theClass };
String message = "DefaultConstructorHidden";
throw new RuntimeException(message);
}
}
/**
*
* This is a convenience method that invokes newInstance(Class) with a Class
* object representing the given type.
*
* @see #getClass(String, ClassLoader)
* @see #newInstance(Class)
*
*/
public static Object newInstance(String className) {
return newInstance(getClass(className));
}
/**
*
* This is a convenience method that invokes newInstance(Class) with a Class
* object loaded by the given ClassLoader
*
* @see #getClass(String, ClassLoader)
* @see #newInstance(Class)
*
*/
public static Object newInstance(String className, ClassLoader classLoader) {
return newInstance(getClass(className, classLoader));
}
/**
*
* This is a setter for the helper object
*
*/
public static void setHelper(ReflectUtilHelper helper) {
_helper = helper;
}
}
/**
*
* @author Joel Hawkins
*
*/
interface ReflectUtilHelper {
boolean exists(String className);
Class getClass(String className);
}
whether method declares the given exception or one of its superclasses
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* Simple utility class for working with the reflection API and handling
* reflection exceptions.
*
* <p>Only intended for internal use.
*
* @author Juergen Hoeller
* @author Rob Harrop
* @author Rod Johnson
* @author Costin Leau
* @since 1.2.2
*/
public abstract class ReflectionUtils {
/**
* Determine whether the given method explicitly declares the given exception
* or one of its superclasses, which means that an exception of that type
* can be propagated as-is within a reflective invocation.
* @param method the declaring method
* @param exceptionType the exception to throw
* @return <code>true</code> if the exception can be thrown as-is;
* <code>false</code> if it needs to be wrapped
*/
public static boolean declaresException(Method method, Class exceptionType) {
Class[] declaredExceptions = method.getExceptionTypes();
for (int i = 0; i < declaredExceptions.length; i++) {
Class declaredException = declaredExceptions[i];
if (declaredException.isAssignableFrom(exceptionType)) {
return true;
}
}
return false;
}
}