Java/Reflection/Exception

Материал из Java эксперт
Перейти к: навигация, поиск

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&eacute 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;
  }
}