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