Utilities to use Java reflection without all of the checked exceptions : Exception « Reflection « Java






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);
}

   
    
  








Related examples in the same category

1.whether method declares the given exception or one of its superclasses
2.Is Checked Exception
3.Get StackTraceElement
4.Check whether given exception is compatible with the exceptions declared in a throws clause