Java/Reflection/Method — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 09:01, 1 июня 2010
Содержание
- 1 An invocation handler that counts the number of calls for all methods in the target class.
- 2 Call a class method with 2 arguments
- 3 Call a member function to get the value
- 4 Call a method dynamically (Reflection)
- 5 Call a method of an object
- 6 Call a static method of a class with reflection
- 7 Call private method
- 8 Checks whether the specified class contains a method matching the specified name.
- 9 Class Reflection: show methods
- 10 Demonstrates dynamic usage of methods
- 11 Demonstrates how to get specific method information
- 12 Demonstration of various method invocation issues
- 13 Fetches all methods of all access types from the supplied class and super classes
- 14 Find a Method on the supplied class with the supplied name and no parameters
- 15 Find a Method on the supplied class with the supplied name and parameter types
- 16 Find method
- 17 Get a given method, and invoke it
- 18 Get all declared methods from a class
- 19 Get all methods including the inherited method. Using the getMethods(), we can only access public methods.
- 20 Get the class name in a static method
- 21 Get the current method name
- 22 Get the current method name With JDK1.5
- 23 Get the methods of a class object
- 24 Getting the Methods of a Class Object: By obtaining a list of all declared methods
- 25 Getting the Methods of a Class Object: By obtaining a list of all public methods, both declared and inherited.
- 26 Getting the Methods of a Class Object: By obtaining a particular Method object.
- 27 Invoke a method using Method class
- 28 Invoke method through Java Reflection API
- 29 Invokes a method, masking with a runtime exception all the exceptions.
- 30 Load a method on the fly
- 31 Make methods that have unspecified number of parameters:pass an array of Objects
- 32 Method modifiers: isSynthetic(), m.isVarArgs(), m.isBridge()
- 33 Method Reflection
- 34 Object Reflection: invoke methods
- 35 Returns method with the specified name
- 36 Show loading a class and finding and calling its Main method
- 37 Sorts methods according to their name, number of parameters, and parameter types.
- 38 The next example calls a class method with 2 arguments:
- 39 To get the calling method
- 40 Using reflection to show all the methods of a class,
An invocation handler that counts the number of calls for all methods in the target class.
<source lang="java">
/*
* file: SomeClassFactory.java * package: oreilly.hcj.proxies * * This software is granted under the terms of the Common Public License, * CPL, which may be found at the following URL: * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm * * Copyright(c) 2003-2005 by the authors indicated in the @author tags. * All Rights are Reserved by the various authors. * ########## DO NOT EDIT ABOVE THIS LINE ########## */
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /**
* An invocation handler that counts the number of calls for all methods in the * target class. * * @author * @version $Revision: 1.2 $ */
public class DemoDynamicProxy {
/** * Run the demonstration. * * @param args Command Line Arguments (ignored). */ public static final void main(final String[] args) { SomeClass proxy = SomeClassFactory.getDynamicSomeClassProxy(); proxy.someMethod(); proxy.someOtherMethod("Our Proxy works!"); InvocationHandler handler = Proxy.getInvocationHandler(proxy); if (handler instanceof MethodCountingHandler) { System.out.println(((MethodCountingHandler)handler).getInvocationCount()); } }
} /* ########## End of File ########## */
</source>
Call a class method with 2 arguments
<source lang="java">
import java.lang.reflect.Method; public class Main {
public static void main(String[] args) throws Exception { Class c = Class.forName("MyClass"); Method m = c.getDeclaredMethod("say", new Class[] { String.class, String.class }); Object i = c.newInstance(); Object r = m.invoke(i, new Object[] { "Hello","World" }); }
} class MyClass {
public void say(String s1, String s2) { System.out.println(s1 + " " + s2); }
}
</source>
Call a member function to get the value
<source lang="java">
// $Id: ReflectionHelper.java 16271 2009-04-07 20:20:12Z hardy.ferentschik $ /*
- JBoss, Home of Professional Open Source
- Copyright 2008, Red Hat Middleware LLC, and individual contributors
- by the @authors tag. See the copyright.txt in the distribution for a
- full listing of individual contributors.
- 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.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map;
/**
* Some reflection utility methods. * * @author Hardy Ferentschik */
public class ReflectionHelper {
public static Object getValue(Member member, Object object) { Object value = null; if ( member instanceof Method ) { Method method = ( Method ) member; try { value = method.invoke( object ); } catch ( IllegalAccessException e ) { throw new RuntimeException( "Unable to access " + method.getName(), e ); } catch ( InvocationTargetException e ) { throw new RuntimeException( "Unable to access " + method.getName(), e ); } } else if ( member instanceof Field ) { Field field = ( Field ) member; try { value = field.get( object ); } catch ( IllegalAccessException e ) { throw new RuntimeException( "Unable to access " + field.getName(), e ); } } return value; }
}
</source>
Call a method dynamically (Reflection)
<source lang="java">
import java.lang.reflect.Method; public class Main {
public static void main(String s[]) throws Exception { String aClass = "Class1"; String aMethod = "class1Method1"; Class params[] = {}; Object paramsObj[] = {}; Class thisClass = Class.forName(aClass); Object iClass = thisClass.newInstance(); Method thisMethod = thisClass.getDeclaredMethod(aMethod, params); System.out.println(thisMethod.invoke(iClass, paramsObj).toString()); }
} class Class1 {
public String class1Method1() { return "Method1"; } public String class1Method2() { return "Method2"; }
}
</source>
Call a method of an object
<source lang="java">
import java.lang.reflect.Method; /**
* Handy reflection routines. */
public abstract class Reflect {
/** * Call a method of an object. */ public static Object callMethod (Object obj, String methodName, Class[] signature, Object[] args) throws Exception { Class cls = obj.getClass (); Method method = cls.getMethod (methodName, signature); return method.invoke (obj, args); }
}
</source>
Call a static method of a class with reflection
<source lang="java">
import java.lang.reflect.Method; /**
* Handy reflection routines. */
public abstract class Reflect {
/** * Call a static method of a class. */ public static Object callStaticMethod (String className, String methodName, Class[] signature, Object[] args) throws Exception { Class cls = Class.forName (className); Method method = cls.getMethod (methodName, signature); return method.invoke (cls, args); }
}
</source>
Call private method
<source lang="java">
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; class AnotherClass {
private void m() { }
} public class MethodTroubleAgain {
public static void main(String... args) { AnotherClass ac = new AnotherClass(); try { Class<?> c = ac.getClass(); Method m = c.getDeclaredMethod("m"); // m.setAccessible(true); // solution Object o = m.invoke(ac); // IllegalAccessException // production code should handle these exceptions more gracefully } catch (NoSuchMethodException x) { x.printStackTrace(); } catch (InvocationTargetException x) { x.printStackTrace(); } catch (IllegalAccessException x) { x.printStackTrace(); } }
}
</source>
Checks whether the specified class contains a method matching the specified name.
<source lang="java">
// $Id: ReflectionHelper.java 16271 2009-04-07 20:20:12Z hardy.ferentschik $ /*
- JBoss, Home of Professional Open Source
- Copyright 2008, Red Hat Middleware LLC, and individual contributors
- by the @authors tag. See the copyright.txt in the distribution for a
- full listing of individual contributors.
- 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.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; /**
* Some reflection utility methods. * * @author Hardy Ferentschik */
public class ReflectionHelper {
/** * Checks whether the specified class contains a method matching the specified name. * * @param clazz The class to check. * @param methodName The method name. * * @return Returnstrue
if the cass contains a property for the specified name,* false
otherwise. */ public static boolean containsMethod(Class<?> clazz, String methodName) { try { clazz.getMethod( "get" + methodName.substring( 0, 1 ).toUpperCase() + methodName.substring( 1 ) ); return true; } catch ( NoSuchMethodException e ) { return false; } }
}
</source>
Class Reflection: show methods
<source lang="java">
/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*
* Copyright (c) 1995-1998 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for NON-COMMERCIAL purposes and without fee is hereby granted * provided that this copyright notice appears in all copies. Please refer to * the file "copyright.html" for further important copyright and licensing * information. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. */
import java.awt.Polygon; import java.lang.reflect.Method; public class SampleMethod {
public static void main(String[] args) { Polygon p = new Polygon(); showMethods(p); } static void showMethods(Object o) { Class c = o.getClass(); Method[] theMethods = c.getMethods(); for (int i = 0; i < theMethods.length; i++) { String methodString = theMethods[i].getName(); System.out.println("Name: " + methodString); String returnString = theMethods[i].getReturnType().getName(); System.out.println(" Return Type: " + returnString); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k++) { String parameterString = parameterTypes[k].getName(); System.out.print(" " + parameterString); } System.out.println(); } }
}
</source>
Demonstrates dynamic usage of methods
<source lang="java">
/*
* file: MethodUsageDemo.java * package: oreilly.hcj.reflection * * This software is granted under the terms of the Common Public License, * CPL, which may be found at the following URL: * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm * * Copyright(c) 2003-2005 by the authors indicated in the @author tags. * All Rights are Reserved by the various authors. * ########## DO NOT EDIT ABOVE THIS LINE ########## */
//package oreilly.hcj.reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.DateFormat; import java.util.Locale; /**
* Demonstrates dynamic usage of methods. * * @author * @version $Revision: 1.3 $ */
public class MethodUsageDemo {
/** Date formatter to be used. */ static final DateFormat DATE_FORMATTER = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); /** * Ouput the values of the "get" methods. * * @param obj * The object to output. * * @throws InvocationTargetException * If an error occurs in calling the get methods. * @throws IllegalAccessException * If the security manager rejects access. */ public static final void outputValues(final Object obj) throws InvocationTargetException, IllegalAccessException { final String PREFIX = "get"; //$NON-NLS-1$ System.out.println("--- Accessing Get Methods ---"); Method[] meths = obj.getClass().getMethods(); for (int idx = 0; idx < meths.length; idx++) { if (meths[idx].getName().startsWith(PREFIX)) { if (meths[idx].getParameterTypes().length == 0) { System.out.print(meths[idx].getName() + " = "); //$NON-NLS-1$ System.out.println(meths[idx].invoke(obj, null)); } } } } /** * Main method. * * @param args * Command line arguments. * * @throws RuntimeException * If an unforseen error occurs. */ public static void main(final String[] args) { try { // person.setBirthDate(DATE_FORMATTER.parse("01/12/1971")); // Output the object. outputValues(new String()); } catch (final Exception ex) { throw new RuntimeException(ex); } }
} /* ########## End of File ########## */
</source>
Demonstrates how to get specific method information
<source lang="java">
import java.lang.reflect.Method; /**
* Demonstrates how to get specific method information. * * @author * @version $Revision: 1.3 $ */
public class SpecificMethodInfoDemo {
public static void main(final String[] args) { final Method byteValueMeth; final Method waitMeth; final Method waitDetailMeth; try { byteValueMeth = Number.class.getMethod("byteValue", null); waitMeth = Number.class.getMethod("wait", new Class[] {}); waitDetailMeth = Number.class.getMethod("wait", new Class[] { long.class, int.class }); } catch (final NoSuchMethodException ex) { throw new RuntimeException(ex); } System.out.println("byteValueMeth = " + byteValueMeth.toString()); System.out.println("waitMeth = " + waitMeth.toString()); System.out.println("waitDetailMeth = " + waitDetailMeth.toString()); }
}
</source>
Demonstration of various method invocation issues
<source lang="java">
/*
* file: VariousMethodDemos.java * package: oreilly.hcj.reflection * * This software is granted under the terms of the Common Public License, * CPL, which may be found at the following URL: * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm * * Copyright(c) 2003-2005 by the authors indicated in the @author tags. * All Rights are Reserved by the various authors. * ########## DO NOT EDIT ABOVE THIS LINE ########## */
import java.lang.reflect.Method; /**
* Demonstration of various method invocation issues. * * @author * @version $Revision$ */
public class VariousMethodDemos {
/** * Run the demo. * * @param args * Command line arguments (ignored). */ public static void main(final String[] args) { try { final Class[] ARG_TYPES = new Class[] { String.class }; Object result = null; Method meth = Integer.class.getMethod("parseInt", ARG_TYPES); result = meth.invoke(null, new Object[] { new String("44") }); System.out.println(result); result = meth.invoke(null, new Object[] { new String("Jonny") }); System.out.println(result); } catch (final Exception ex) { ex.printStackTrace(); } }
} /* ########## End of File ########## */
</source>
Fetches all methods of all access types from the supplied class and super classes
<source lang="java">
import java.util.Map; import java.util.HashMap; import java.util.Collection; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.SortedSet; import java.util.TreeSet; import java.util.Queue; import java.util.LinkedList; import java.util.SortedMap; import java.util.TreeMap; import java.util.Arrays; import java.util.concurrent.ConcurrentHashMap; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import static java.lang.reflect.Modifier.isPublic; import java.beans.PropertyDescriptor; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.IntrospectionException; /**
* Common utilty methods that are useful when working with reflection. * * @author Tim Fennell */
public class ReflectUtil {
/** A cache of property descriptors by class and property name */ private static Map<Class<?>, Map<String, PropertyDescriptor>> propertyDescriptors = new ConcurrentHashMap<Class<?>, Map<String, PropertyDescriptor>>(); /** Static helper class, shouldn"t be constructed. */ private ReflectUtil() {} /** * Holds a map of commonly used interface types (mostly collections) to a class that * implements the interface and will, by default, be instantiated when an instance * of the interface is needed. */ protected static final Map<Class<?>,Class<?>> interfaceImplementations = new HashMap<Class<?>,Class<?>>(); /** * Holds a map of primitive type to the default value for that primitive type. Isn"t it * odd that there"s no way to get this programmatically from the Class objects? */ protected static final Map<Class<?>,Object> primitiveDefaults = new HashMap<Class<?>,Object>(); static { interfaceImplementations.put(Collection.class, ArrayList.class); interfaceImplementations.put(List.class, ArrayList.class); interfaceImplementations.put(Set.class, HashSet.class); interfaceImplementations.put(SortedSet.class, TreeSet.class); interfaceImplementations.put(Queue.class, LinkedList.class); interfaceImplementations.put(Map.class, HashMap.class); interfaceImplementations.put(SortedMap.class, TreeMap.class); primitiveDefaults.put(Boolean.TYPE, false); primitiveDefaults.put(Character.TYPE, "\0"); primitiveDefaults.put(Byte.TYPE, new Byte("0")); primitiveDefaults.put(Short.TYPE, new Short("0")); primitiveDefaults.put(Integer.TYPE, new Integer(0)); primitiveDefaults.put(Long.TYPE, new Long(0l)); primitiveDefaults.put(Float.TYPE, new Float(0f)); primitiveDefaults.put(Double.TYPE, new Double(0.0)); } /** * The set of method that annotation classes inherit, and should be avoided when * toString()ing an annotation class. */ private static final Set<String> INHERITED_ANNOTATION_METHODS = new HashSet(Arrays.asList("toString", "equals", "hashCode", "annotationType")); /** * Looks up the default implementing type for the supplied interface. This is done * based on a static map of known common interface types and implementing classes. * * @param iface an interface for which an implementing class is needed * @return a Class object representing the implementing type, or null if one is * not found */ public static Class<?> getImplementingClass(Class<?> iface) { return interfaceImplementations.get(iface); } /** * Attempts to determine an implementing class for the interface provided and instantiate * it using a default constructor. * * @param interfaceType an interface (or abstract class) to make an instance of * @return an instance of the interface type supplied * @throws InstantiationException if no implementation type has been configured * @throws IllegalAccessException if thrown by the JVM during class instantiation */ @SuppressWarnings("unchecked") public static <T> T getInterfaceInstance(Class<T> interfaceType) throws InstantiationException, IllegalAccessException { Class impl = getImplementingClass(interfaceType); if (impl == null) { throw new InstantiationException( "Stripes needed to instantiate a property who"s declared type as an " + "interface (which obviously cannot be instantiated. The interface is not " + "one that Stripes is aware of, so no implementing class was known. The " + "interface type was: "" + interfaceType.getName() + "". To fix this " + "you"ll need to do one of three things. 1) Change the getter/setter methods " + "to use a concrete type so that Stripes can instantiate it. 2) in the bean"s " + "setContext() method pre-instantiate the property so Stripes doesn"t have to. " + "3) Bug the Stripes author ;) If the interface is a JDK type it can easily be " + "fixed. If not, if enough people ask, a generic way to handle the problem " + "might get implemented."); } else { return (T) impl.newInstance(); } } /** * Utility method used to load a class. Any time that Stripes needs to load of find a * class by name it uses this method. As a result any time the classloading strategy * needs to change it can be done in one place! Currently uses * {@code Thread.currentThread().getContextClassLoader().loadClass(String)}. * * @param name the fully qualified (binary) name of the class to find or load * @return the Class object representing the class * @throws ClassNotFoundException if the class cannot be loaded */ @SuppressWarnings("unchecked") // this allows us to assign without casting public static Class findClass(String name) throws ClassNotFoundException { return Thread.currentThread().getContextClassLoader().loadClass(name); } /***
A better (more concise) toString method for annotation types that yields a String * that should look more like the actual usage of the annotation in a class. The String produced * is similar to that produced by calling toString() on the annotation directly, with the * following differences:
**
-
*
- Uses the classes simple name instead of it"s fully qualified name. *
- Only outputs attributes that are set to non-default values.
**
If, for some unforseen reason, an exception is thrown within this method it will be * caught and the return value will be {@code ann.toString()}. * * @param ann the annotation to convert to a human readable String * @return a human readable String form of the annotation and it"s attributes */ public static String toString(Annotation ann) { try { Class<? extends Annotation> type = ann.annotationType(); StringBuilder builder = new StringBuilder(128); builder.append("@"); builder.append(type.getSimpleName()); boolean appendedAnyParameters = false; Method[] methods = type.getMethods(); for (Method method : methods) { if (!INHERITED_ANNOTATION_METHODS.contains(method.getName())) { Object defaultValue = method.getDefaultValue(); Object actualValue = method.invoke(ann); // If we have arrays, they have to be treated a little differently Object[] defaultArray = null, actualArray = null; if ( Object[].class.isAssignableFrom(method.getReturnType()) ) { defaultArray = (Object[]) defaultValue; actualArray = (Object[]) actualValue; } // Only print an attribute if it isn"t set to the default value if ( (defaultArray != null && !Arrays.equals(defaultArray, actualArray)) || (defaultArray == null && !actualValue.equals(defaultValue)) ) { if (appendedAnyParameters) { builder.append(", "); } else { builder.append("("); } builder.append(method.getName()); builder.append("="); if (actualArray != null) { builder.append( Arrays.toString(actualArray) ); } else { builder.append(actualValue); } appendedAnyParameters = true; } } } if (appendedAnyParameters) { builder.append(")"); } return builder.toString(); } catch (Exception e) { return ann.toString(); } } /** * Fetches all methods of all access types from the supplied class and super * classes. Methods that have been overridden in the inheritance hierarchy are * only returned once, using the instance lowest down the hierarchy. * * @param clazz the class to inspect * @return a collection of methods */ public static Collection<Method> getMethods(Class<?> clazz) { Collection<Method> found = new ArrayList<Method>(); while (clazz != null) { for (Method m1 : clazz.getDeclaredMethods()) { boolean overridden = false; for (Method m2 : found) { if ( m2.getName().equals(m1.getName()) && Arrays.deepEquals(m1.getParameterTypes(), m2.getParameterTypes())) { overridden = true; break; } } if (!overridden) found.add(m1); } clazz = clazz.getSuperclass(); } return found; } /** * Fetches all fields of all access types from the supplied class and super * classes. Fieldss that have been overridden in the inheritance hierarchy are * only returned once, using the instance lowest down the hierarchy. * * @param clazz the class to inspect * @return a collection of fields */ public static Collection<Field> getFields(Class<?> clazz) { Map<String,Field> fields = new HashMap<String, Field>(); while (clazz != null) { for (Field field : clazz.getDeclaredFields()) { if ( !fields.containsKey(field.getName()) ) { fields.put(field.getName(), field); } } clazz = clazz.getSuperclass(); } return fields.values(); } /** * Fetches the property descriptor for the named property of the supplied class. To * speed things up a cache is maintained of propertyName to PropertyDescriptor for * each class used with this method. If there is no property with the specified name, * returns null. * * @param clazz the class who"s properties to examine * @param property the String name of the property to look for * @return the PropertyDescriptor or null if none is found with a matching name */ public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String property) { Map<String,PropertyDescriptor> pds = propertyDescriptors.get(clazz); if (pds == null) { try { BeanInfo info = Introspector.getBeanInfo(clazz); PropertyDescriptor[] descriptors = info.getPropertyDescriptors(); pds = new HashMap<String, PropertyDescriptor>(); for (PropertyDescriptor descriptor : descriptors) { pds.put(descriptor.getName(), descriptor); } propertyDescriptors.put(clazz, pds); } catch (IntrospectionException ie) { throw new RuntimeException("Could not examine class "" + clazz.getName() + "" using Introspector.getBeanInfo() to determine property information.", ie); } } return pds.get(property); } /** * <p>Attempts to find an accessible version of the method passed in, where accessible * is defined as the method itself being public and the declaring class being public. * Mostly useful as a workaround to the situation when * {@link PropertyDescriptor#getReadMethod()} and/or * {@link java.beans.PropertyDescriptor#getWriteMethod()} returns methods that are not * accessible (usually due to public implementations of interface methods in private * classes).
**
Checks the method passed in and if it already meets these criteria it is returned * immediately. In general this leads to very little performance overhead
**
If the method does not meet the criteria then the class" interfaces are scanned * for a matching method. If one is not found, then the class" superclass hierarchy * is searched. Finally, if no matching method can be found the original method is * returned.
* * @param m a method that may or may not be accessible * @return either an accessible version of the same method, or the method passed in if * an accessible version cannot be found */ public static Method findAccessibleMethod(final Method m) { // If the passed in method is accessible, then just give it back. if (isPublic(m.getModifiers()) && isPublic(m.getDeclaringClass().getModifiers())) return m; if (m.isAccessible()) return m; final Class<?> clazz = m.getDeclaringClass(); final String name = m.getName(); final Class<?>[] ptypes = m.getParameterTypes(); // Else, loop through the interfaces for the declaring class, looking for a // public version of the method that we can call for (Class<?> iface : clazz.getInterfaces()) { try { Method m2 = iface.getMethod(name, ptypes); if (m2.isAccessible()) return m2; if (isPublic(iface.getModifiers()) && isPublic(m2.getModifiers())) return m2; } catch (NoSuchMethodException nsme) { /* Not Unexpected. */ } } // Else loop through the superclasses looking for a public method Class<?> c = clazz.getSuperclass(); while (c != null) { try { Method m2 = c.getMethod(name, ptypes); if (m2.isAccessible()) return m2; if (isPublic(c.getModifiers()) && isPublic(m2.getModifiers())) return m2; } catch (NoSuchMethodException nsme) { /* Not Unexpected. */ } c = c.getSuperclass(); } // If we haven"t found anything at this point, just give up! return m; }
/** * Looks for an instance (i.e. non-static) public field with the matching name and * returns it if one exists. If no such field exists, returns null. * * @param clazz the clazz who"s fields to examine * @param property the name of the property/field to look for * @return the Field object or null if no matching field exists */ public static Field getField(Class<?> clazz, String property) { try { Field field = clazz.getField(property); return !Modifier.isStatic(field.getModifiers()) ? field : null; } catch (NoSuchFieldException nsfe) { return null; } } /** * Returns an appropriate default value for the class supplied. Mirrors the defaults used * when the JVM initializes instance variables. * * @param clazz the class for which to find the default value * @return null for non-primitive types and an appropriate wrapper instance for primitives */ public static Object getDefaultValue(Class<?> clazz) { if (clazz.isPrimitive()) { return primitiveDefaults.get(clazz); } else { return null; } } /** * Returns a set of all interfaces implemented by class supplied. This includes all * interfaces directly implemented by this class as well as those implemented by * superclasses or interface superclasses. * * @param clazz * @return all interfaces implemented by this class */ public static Set<Class<?>> getImplementedInterfaces(Class<?> clazz) { Set<Class<?>> interfaces = new HashSet<Class<?>>(); if (clazz.isInterface()) interfaces.add(clazz); while (clazz != null) { for (Class<?> iface : clazz.getInterfaces()) interfaces.addAll(getImplementedInterfaces(iface)); clazz = clazz.getSuperclass(); } return interfaces; } /** * Returns an array of Type objects representing the actual type arguments * to targetType used by clazz. * * @param clazz the implementing class (or subclass) * @param targetType the implemented generic class or interface * @return an array of Type objects or null */ public static Type[] getActualTypeArguments(Class<?> clazz, Class<?> targetType) { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(clazz); if (targetType.isInterface()) classes.addAll(getImplementedInterfaces(clazz)); Class<?> superClass = clazz.getSuperclass(); while (superClass != null) { classes.add(superClass); superClass = superClass.getSuperclass(); } for (Class<?> search : classes) { for (Type type : (targetType.isInterface() ? search.getGenericInterfaces() : new Type[] { search.getGenericSuperclass() })) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; if (targetType.equals(parameterizedType.getRawType())) return parameterizedType.getActualTypeArguments(); } } } return null; }
}
</source>
Find a Method on the supplied class with the supplied name and no parameters
<source lang="java">
/*
* 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. **
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 {
/**
* Attempt to find a {@link Method} on the supplied class with the supplied name
* and no parameters. Searches all superclasses up to Object
.
* <p>Returns null
if no {@link Method} can be found.
* @param clazz the class to introspect
* @param name the name of the method
* @return the Method object, or null
if none found
*/
public static Method findMethod(Class clazz, String name) {
return findMethod(clazz, name, new Class[0]);
}
/**
* Attempt to find a {@link Method} on the supplied class with the supplied name
* and parameter types. Searches all superclasses up to Object
.
* <p>Returns null
if no {@link Method} can be found.
* @param clazz the class to introspect
* @param name the name of the method
* @param paramTypes the parameter types of the method
* @return the Method object, or null
if none found
*/
public static Method findMethod(Class clazz, String name, Class[] paramTypes) {
Class searchType = clazz;
while (!Object.class.equals(searchType) && searchType != null) {
Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (name.equals(method.getName()) && Arrays.equals(paramTypes, method.getParameterTypes())) {
return method;
}
}
searchType = searchType.getSuperclass();
}
return null;
}
}
</source>
Find a Method on the supplied class with the supplied name and parameter types
<source lang="java">
/*
* 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 {
/** * Attempt to find a {@link Method} on the supplied class with the supplied name * and no parameters. Searches all superclasses up toObject
. * <p>Returnsnull
if no {@link Method} can be found. * @param clazz the class to introspect * @param name the name of the method * @return the Method object, ornull
if none found */ public static Method findMethod(Class clazz, String name) { return findMethod(clazz, name, new Class[0]); } /** * Attempt to find a {@link Method} on the supplied class with the supplied name * and parameter types. Searches all superclasses up toObject
. * <p>Returnsnull
if no {@link Method} can be found. * @param clazz the class to introspect * @param name the name of the method * @param paramTypes the parameter types of the method * @return the Method object, ornull
if none found */ public static Method findMethod(Class clazz, String name, Class[] paramTypes) { Class searchType = clazz; while (!Object.class.equals(searchType) && searchType != null) { Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods()); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (name.equals(method.getName()) && Arrays.equals(paramTypes, method.getParameterTypes())) { return method; } } searchType = searchType.getSuperclass(); } return null; }
}
</source>
Find method
<source lang="java">
// //$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $ //Copyright 2006 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //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.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; public class IntrospectionUtil {
public static Method findMethod(Class clazz, String methodName, Class[] args, boolean checkInheritance, boolean strictArgs) throws NoSuchMethodException { if (clazz == null) throw new NoSuchMethodException("No class"); if (methodName == null || methodName.trim().equals("")) throw new NoSuchMethodException("No method name"); Method method = null; Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length && method == null; i++) { if (methods[i].getName().equals(methodName) && checkParams(methods[i].getParameterTypes(), (args == null ? new Class[] {} : args), strictArgs)) { method = methods[i]; } } if (method != null) { return method; } else if (checkInheritance) return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs); else throw new NoSuchMethodException("No such method " + methodName + " on class " + clazz.getName()); } public static Field findField(Class clazz, String targetName, Class targetType, boolean checkInheritance, boolean strictType) throws NoSuchFieldException { if (clazz == null) throw new NoSuchFieldException("No class"); if (targetName == null) throw new NoSuchFieldException("No field name"); try { Field field = clazz.getDeclaredField(targetName); if (strictType) { if (field.getType().equals(targetType)) return field; } else { if (field.getType().isAssignableFrom(targetType)) return field; } if (checkInheritance) { return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), targetName, targetType, strictType); } else throw new NoSuchFieldException("No field with name " + targetName + " in class " + clazz.getName() + " of type " + targetType); } catch (NoSuchFieldException e) { return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), targetName, targetType, strictType); } } public static boolean isInheritable(Package pack, Member member) { if (pack == null) return false; if (member == null) return false; int modifiers = member.getModifiers(); if (Modifier.isPublic(modifiers)) return true; if (Modifier.isProtected(modifiers)) return true; if (!Modifier.isPrivate(modifiers) && pack.equals(member.getDeclaringClass().getPackage())) return true; return false; } public static boolean checkParams(Class[] formalParams, Class[] actualParams, boolean strict) { if (formalParams == null && actualParams == null) return true; if (formalParams == null && actualParams != null) return false; if (formalParams != null && actualParams == null) return false; if (formalParams.length != actualParams.length) return false; if (formalParams.length == 0) return true; int j = 0; if (strict) { while (j < formalParams.length && formalParams[j].equals(actualParams[j])) j++; } else { while ((j < formalParams.length) && (formalParams[j].isAssignableFrom(actualParams[j]))) { j++; } } if (j != formalParams.length) { return false; } return true; } public static boolean isSameSignature(Method methodA, Method methodB) { if (methodA == null) return false; if (methodB == null) return false; List parameterTypesA = Arrays.asList(methodA.getParameterTypes()); List parameterTypesB = Arrays.asList(methodB.getParameterTypes()); if (methodA.getName().equals(methodB.getName()) && parameterTypesA.containsAll(parameterTypesB)) return true; return false; } public static boolean isTypeCompatible(Class formalType, Class actualType, boolean strict) { if (formalType == null && actualType != null) return false; if (formalType != null && actualType == null) return false; if (formalType == null && actualType == null) return true; if (strict) return formalType.equals(actualType); else return formalType.isAssignableFrom(actualType); } public static boolean containsSameMethodSignature(Method method, Class c, boolean checkPackage) { if (checkPackage) { if (!c.getPackage().equals(method.getDeclaringClass().getPackage())) return false; } boolean samesig = false; Method[] methods = c.getDeclaredMethods(); for (int i = 0; i < methods.length && !samesig; i++) { if (IntrospectionUtil.isSameSignature(method, methods[i])) samesig = true; } return samesig; } public static boolean containsSameFieldName(Field field, Class c, boolean checkPackage) { if (checkPackage) { if (!c.getPackage().equals(field.getDeclaringClass().getPackage())) return false; } boolean sameName = false; Field[] fields = c.getDeclaredFields(); for (int i = 0; i < fields.length && !sameName; i++) { if (fields[i].getName().equals(field.getName())) sameName = true; } return sameName; } protected static Method findInheritedMethod(Package pack, Class clazz, String methodName, Class[] args, boolean strictArgs) throws NoSuchMethodException { if (clazz == null) throw new NoSuchMethodException("No class"); if (methodName == null) throw new NoSuchMethodException("No method name"); Method method = null; Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length && method == null; i++) { if (methods[i].getName().equals(methodName) && isInheritable(pack, methods[i]) && checkParams(methods[i].getParameterTypes(), args, strictArgs)) method = methods[i]; } if (method != null) { return method; } else return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args, strictArgs); } protected static Field findInheritedField(Package pack, Class clazz, String fieldName, Class fieldType, boolean strictType) throws NoSuchFieldException { if (clazz == null) throw new NoSuchFieldException("No class"); if (fieldName == null) throw new NoSuchFieldException("No field name"); try { Field field = clazz.getDeclaredField(fieldName); if (isInheritable(pack, field) && isTypeCompatible(fieldType, field.getType(), strictType)) return field; else return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), fieldName, fieldType, strictType); } catch (NoSuchFieldException e) { return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), fieldName, fieldType, strictType); } }
}
</source>
Get a given method, and invoke it
<source lang="java">
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS"" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */
import java.lang.reflect.Method; /**
* This class is just here to give us something to work on, with a println() * call that will prove we got here. */
class X {
public void work(String s) { System.out.println("Working on \"" + s + "\""); }
} /**
* Get a given method, and invoke it. * * @author Ian F. Darwin, http://www.darwinsys.ru/ * @version $Id: GetMethod.java,v 1.3 2004/02/09 03:33:51 ian Exp $ */
public class GetMethod {
public static void main(String[] argv) { try { Class clX = X.class; // or Class.forName("X"); // To find a method we need the array of matching Class types. Class[] argTypes = { String.class }; // Now find a Method object for the given method. Method worker = clX.getMethod("work", argTypes); // To INVOKE the method, we need its actual arguments, as an array. Object[] theData = { "Chocolate Chips" }; // The obvious last step: invoke the method. worker.invoke(new X(), theData); } catch (Exception e) { System.err.println("Invoke() failed: " + e); } }
}
</source>
Get all declared methods from a class
<source lang="java">
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Main{
public static void main(String args[]) throws Exception { Class c = Class.forName("MyClass"); System.out.println("\nMethods:"); Method methods[] = c.getDeclaredMethods(); for (Method meth : methods) System.out.println(" " + meth); }
} class MyClass {
private int count; MyClass(int c) { count = c; } MyClass() { count = 0; } void setCount(int c) { count = c; } int getCount() { return count; } void showcount() { System.out.println("count is " + count); }
}
</source>
Get all methods including the inherited method. Using the getMethods(), we can only access public methods.
<source lang="java">
import java.lang.reflect.Method; class GetMethods {
public int add(int numberA, int numberB) { return numberA + numberB; } protected int multiply(int numberA, int numberB) { return numberA * numberB; } private double div(int numberA, int numberB) { return numberA / numberB; }
} public class Main {
public static void main(String[] args) throws Exception { GetMethods object = new GetMethods(); Class clazz = object.getClass(); Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println("Method name = " + method.getName()); System.out.println("Method return type = " + method.getReturnType().getName()); Class[] paramTypes = method.getParameterTypes(); for (Class c : paramTypes) { System.out.println("Param type = " + c.getName()); } } Method method = clazz.getMethod("add", new Class[] { int.class, int.class }); System.out.println("Method name: " + method.getName()); }
}
</source>
Get the class name in a static method
<source lang="java">
public class Main{
public static void main(java.lang.String[] args) { System.out.println("in " + new CurrentClassGetter().getClassName() + " class"); }
}
class CurrentClassGetter extends SecurityManager { public String getClassName() { return getClassContext()[1].getName(); }
}
</source>
Get the current method name
<source lang="java">
public class Main{
public static void main(String args[]) { System.out.println (new Exception().getStackTrace()[0].getMethodName()); }
}
</source>
Get the current method name With JDK1.5
<source lang="java">
public class Main {
public static void main(String args[]) { trace(Thread.currentThread().getStackTrace()); } public static void trace(StackTraceElement e[]) { boolean doNext = false; for (StackTraceElement s : e) { if (doNext) { System.out.println(s.getMethodName()); return; } doNext = s.getMethodName().equals("getStackTrace"); } }
}
</source>
Get the methods of a class object
<source lang="java">
import java.lang.reflect.Method; class GetMethods {
public int add(int numberA, int numberB) { return numberA + numberB; } protected int multiply(int numberA, int numberB) { return numberA * numberB; } private double div(int numberA, int numberB) { return numberA / numberB; }
} public class Main {
public static void main(String[] args) throws Exception { GetMethods object = new GetMethods(); Class clazz = object.getClass(); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { System.out.println("Method name = " + method.getName()); System.out.println("Method return type = " + method.getReturnType().getName()); Class[] paramTypes = method.getParameterTypes(); for (Class c : paramTypes) { System.out.println("Param type = " + c.getName()); } } }
}
</source>
Getting the Methods of a Class Object: By obtaining a list of all declared methods
<source lang="java">
import java.lang.reflect.Method; public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.lang.String.class; Method[] methods = cls.getDeclaredMethods(); }
}
</source>
Getting the Methods of a Class Object: By obtaining a list of all public methods, both declared and inherited.
<source lang="java">
import java.lang.reflect.Method; public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.lang.String.class; Method[] methods = cls.getMethods(); for (int i = 0; i < methods.length; i++) { Class returnType = methods[i].getReturnType(); Class[] paramTypes = methods[i].getParameterTypes(); System.out.println(methods[i]); } }
}
</source>
Getting the Methods of a Class Object: By obtaining a particular Method object.
<source lang="java">
import java.lang.reflect.Method; public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.lang.String.class; Method method = cls.getMethod("substring", new Class[] { int.class }); System.out.println(method); }
}
</source>
Invoke a method using Method class
<source lang="java">
import java.lang.reflect.Method; public class Main {
public static void main(String[] args) throws Exception { MyClass object = new MyClass(); Class clazz = object.getClass(); Method method = clazz.getMethod("add", new Class[] { int.class, int.class }); Object result = method.invoke(object, new Object[] { 10, 10 }); System.out.println("Result = " + result); method = clazz.getMethod("multiply", new Class[] { int.class, int.class }); result = method.invoke(object, new Object[] { 10, 10 }); System.out.println("Result = " + result); }
} class MyClass{
public int add(int numberA, int numberB) { return numberA + numberB; } public int multiply(int numberA, int numberB) { return numberA * numberB; } public double div(int numberA, int numberB) { return numberA / numberB; }
}
</source>
Invoke method through Java Reflection API
<source lang="java">
/*
* Copyright (c) 2000 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 2nd Edition. * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied. * You may study, use, and modify it for any non-commercial purpose. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book (recommended), * visit http://www.davidflanagan.ru/javaexamples2. */
import java.awt.event.*; import java.beans.*; import java.lang.reflect.*; import java.io.*; import java.util.*; /**
* This class represents a Method, the list of arguments to be passed to that * method, and the object on which the method is to be invoked. The invoke() * method invokes the method. The actionPerformed() method does the same thing, * allowing this class to implement ActionListener and be used to respond to * ActionEvents generated in a GUI or elsewhere. The static parse() method * parses a string representation of a method and its arguments. */
public class Command implements ActionListener {
Method m; // The method to be invoked Object target; // The object to invoke it on Object[] args; // The arguments to pass to the method // An empty array; used for methods with no arguments at all. static final Object[] nullargs = new Object[] {}; /** This constructor creates a Command object for a no-arg method */ public Command(Object target, Method m) { this(target, m, nullargs); } /** * This constructor creates a Command object for a method that takes the * specified array of arguments. Note that the parse() method provides * another way to create a Command object */ public Command(Object target, Method m, Object[] args) { this.target = target; this.m = m; this.args = args; } /** * Invoke the Command by calling the method on its target, and passing the * arguments. See also actionPerformed() which does not throw the checked * exceptions that this method does. */ public void invoke() throws IllegalAccessException, InvocationTargetException { m.invoke(target, args); // Use reflection to invoke the method } /** * This method implements the ActionListener interface. It is like invoke() * except that it catches the exceptions thrown by that method and rethrows * them as an unchecked RuntimeException */ public void actionPerformed(ActionEvent e) { try { invoke(); // Call the invoke method } catch (InvocationTargetException ex) { // but handle the exceptions throw new RuntimeException("Command: " + ex.getTargetException().toString()); } catch (IllegalAccessException ex) { throw new RuntimeException("Command: " + ex.toString()); } } /** * This static method creates a Command using the specified target object, * and the specified string. The string should contain method name followed * by an optional parenthesized comma-separated argument list and a * semicolon. The arguments may be boolean, integer or double literals, or * double-quoted strings. The parser is lenient about missing commas, * semicolons and quotes, but throws an IOException if it cannot parse the * string. */ public static Command parse(Object target, String text) throws IOException { String methodname; // The name of the method ArrayList args = new ArrayList(); // Hold arguments as we parse them. ArrayList types = new ArrayList(); // Hold argument types. // Convert the string into a character stream, and use the // StreamTokenizer class to convert it into a stream of tokens StreamTokenizer t = new StreamTokenizer(new StringReader(text)); // The first token must be the method name int c = t.nextToken(); // read a token if (c != t.TT_WORD) // check the token type throw new IOException("Missing method name for command"); methodname = t.sval; // Remember the method name // Now we either need a semicolon or a open paren c = t.nextToken(); if (c == "(") { // If we see an open paren, then parse an arg list for (;;) { // Loop "till end of arglist c = t.nextToken(); // Read next token if (c == ")") { // See if we"re done parsing arguments. c = t.nextToken(); // If so, parse an optional semicolon if (c != ";") t.pushBack(); break; // Now stop the loop. } // Otherwise, the token is an argument; figure out its type if (c == t.TT_WORD) { // If the token is an identifier, parse boolean literals, // and treat any other tokens as unquoted string literals. if (t.sval.equals("true")) { // Boolean literal args.add(Boolean.TRUE); types.add(boolean.class); } else if (t.sval.equals("false")) { // Boolean literal args.add(Boolean.FALSE); types.add(boolean.class); } else { // Assume its a string args.add(t.sval); types.add(String.class); } } else if (c == """) { // If the token is a quoted string args.add(t.sval); types.add(String.class); } else if (c == t.TT_NUMBER) { // If the token is a number int i = (int) t.nval; if (i == t.nval) { // Check if its an integer // Note: this code treats a token like "2.0" as an int! args.add(new Integer(i)); types.add(int.class); } else { // Otherwise, its a double args.add(new Double(t.nval)); types.add(double.class); } } else { // Any other token is an error throw new IOException("Unexpected token " + t.sval + " in argument list of " + methodname + "()."); } // Next should be a comma, but we don"t complain if its not c = t.nextToken(); if (c != ",") t.pushBack(); } } else if (c != ";") { // if a method name is not followed by a paren t.pushBack(); // then allow a semi-colon but don"t require it. } // We"ve parsed the argument list. // Next, convert the lists of argument values and types to arrays Object[] argValues = args.toArray(); Class[] argtypes = (Class[]) types.toArray(new Class[argValues.length]); // At this point, we"ve got a method name, and arrays of argument // values and types. Use reflection on the class of the target object // to find a method with the given name and argument types. Throw // an exception if we can"t find the named method. Method method; try { method = target.getClass().getMethod(methodname, argtypes); } catch (Exception e) { throw new IOException("No such method found, or wrong argument " + "types: " + methodname); } // Finally, create and return a Command object, using the target object // passed to this method, the Method object we obtained above, and // the array of argument values we parsed from the string. return new Command(target, method, argValues); } public static void main(String[] args) throws IOException { javax.swing.JFrame f = new javax.swing.JFrame("Command Test"); javax.swing.JButton b1 = new javax.swing.JButton("Tick"); javax.swing.JButton b2 = new javax.swing.JButton("Tock"); javax.swing.JLabel label = new javax.swing.JLabel("Hello world"); java.awt.Container pane = f.getContentPane(); pane.add(b1, java.awt.BorderLayout.WEST); pane.add(b2, java.awt.BorderLayout.EAST); pane.add(label, java.awt.BorderLayout.NORTH); b1.addActionListener(Command.parse(label, "setText(\"tick\");")); b2.addActionListener(Command.parse(label, "setText(\"tock\");")); f.pack(); f.show(); }
}
</source>
Invokes a method, masking with a runtime exception all the exceptions.
<source lang="java">
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Main {
/** * Invokes a method, masking with a runtime exception all the exceptions. * * @param obj The object from which a method will be called. * @param method The method to call. * @param args The arguments of the method. * @return The object returned, if the method is not "void". * @since 2.0.7 */ public static Object invokeMethod(Object obj, Method method, Object... args) { try { return method.invoke(obj, args); } catch (IllegalArgumentException e) { throw new RuntimeException("The arguments for "" + method.getName() + "" in class "" + obj.getClass().getName() + "" are not valid", e); } catch (IllegalAccessException e) { throw new RuntimeException("Cannot access "" + method.getName() + "" in class "" + obj.getClass().getName() + """, e); } catch (InvocationTargetException e) { throw new RuntimeException( "An exception has been thrown inside "" + method.getName() + "" in class "" + obj.getClass().getName() + """, e); } }
}
</source>
Load a method on the fly
<source lang="java">
import java.lang.reflect.Method; public class MainClass {
public static void main(String[] args) throws Exception { printTable(10, MethodReflection.class.getMethod("square", new Class[] { double.class })); printTable( 10, java.lang.Math.class.getMethod("sqrt", new Class[] { double.class })); } public static double square(double x) { return x * x; } public static void printTable(int n, Method f) { System.out.println(f); try { Object[] args = { new Double(n) }; Double d = (Double) f.invoke(null, args); double y = d.doubleValue(); System.out.println(y); } catch (Exception e) { System.out.println(e); } }
}
</source>
Make methods that have unspecified number of parameters:pass an array of Objects
<source lang="java">
public class Main {
public static void main(String args[]) { myMethod(new Object[] { "value 1", new Integer(2), "value n" }); } public static void myMethod(Object parms[]) { for (int i = 0; i < parms.length; i++) System.out.println(parms[i]); }
}
</source>
Method modifiers: isSynthetic(), m.isVarArgs(), m.isBridge()
<source lang="java">
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import static java.lang.System.out; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class MethodModifierSpy {
private static int count; private static synchronized void inc() { count++; } private static synchronized int cnt() { return count; } public static void main(String... args) { try { Class<?> c = Class.forName(args[0]); Method[] allMethods = c.getDeclaredMethods(); for (Method m : allMethods) { if (!m.getName().equals(args[1])) { continue; } out.format("%s%n", m.toGenericString()); out.format(" Modifiers: %s%n", Modifier.toString(m.getModifiers())); out.format(" [ synthetic=%-5b var_args=%-5b bridge=%-5b ]%n", m .isSynthetic(), m.isVarArgs(), m.isBridge()); inc(); } out.format("%d matching overload%s found%n", cnt(), (cnt() == 1 ? "" : "s")); // production code should handle this exception more gracefully } catch (ClassNotFoundException x) { x.printStackTrace(); } }
}
</source>
Method Reflection
<source lang="java">
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class MainClass {
public static void main(String[] args) { String name = "java.util.Date"; try { Class cl = Class.forName(name); Class supercl = cl.getSuperclass(); System.out.println("class " + name); System.out.println("Its methods:"); printMethods(cl); System.out.println(); } catch (ClassNotFoundException e) { System.out.println("Class not found."); } } public static void printMethods(Class cl) { Method[] methods = cl.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { Method m = methods[i]; Class retType = m.getReturnType(); Class[] paramTypes = m.getParameterTypes(); String name = m.getName(); System.out.print(Modifier.toString(m.getModifiers())); System.out.print(" " + retType.getName() + " " + name + "("); for (int j = 0; j < paramTypes.length; j++) { if (j > 0) System.out.print(", "); System.out.print(paramTypes[j].getName()); } System.out.println(");"); } }
}
</source>
Object Reflection: invoke methods
<source lang="java">
/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*
* Copyright (c) 1995-1998 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for NON-COMMERCIAL purposes and without fee is hereby granted * provided that this copyright notice appears in all copies. Please refer to * the file "copyright.html" for further important copyright and licensing * information. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY * LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. */
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class SampleInvoke {
public static void main(String[] args) { String firstWord = "Hello "; String secondWord = "everybody."; String bothWords = append(firstWord, secondWord); System.out.println(bothWords); } public static String append(String firstWord, String secondWord) { String result = null; Class c = String.class; Class[] parameterTypes = new Class[] { String.class }; Method concatMethod; Object[] arguments = new Object[] { secondWord }; try { concatMethod = c.getMethod("concat", parameterTypes); result = (String) concatMethod.invoke(firstWord, arguments); } catch (NoSuchMethodException e) { System.out.println(e); } catch (IllegalAccessException e) { System.out.println(e); } catch (InvocationTargetException e) { System.out.println(e); } return result; }
}
</source>
Returns method with the specified name
<source lang="java">
// $Id: ReflectionHelper.java 16271 2009-04-07 20:20:12Z hardy.ferentschik $ /*
- JBoss, Home of Professional Open Source
- Copyright 2008, Red Hat Middleware LLC, and individual contributors
- by the @authors tag. See the copyright.txt in the distribution for a
- full listing of individual contributors.
- 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.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; /**
* Some reflection utility methods. * * @author Hardy Ferentschik */
public class ReflectionHelper {
/** * Returns the method with the specified name ornull
if it does not exist. * * @param clazz The class to check. * @param methodName The method name. * * @return Returns the method with the specified name ornull
if it does not exist. */ public static Method getMethod(Class<?> clazz, String methodName) { try { return clazz.getMethod( "get" + methodName.substring( 0, 1 ).toUpperCase() + methodName.substring( 1 ) ); } catch ( NoSuchMethodException e ) { return null; } }
}
</source>
Show loading a class and finding and calling its Main method
<source lang="java">
import java.lang.reflect.Method; /**
* Show loading a class and finding and calling its Main method. * * @author Ian F. Darwin, http://www.darwinsys.ru/ * @version $Id: InvokeMain.java,v 1.3 2004/02/09 03:33:54 ian Exp $ */
public class InvokeMain {
public static void main(String[] argv) { //+ try { // First, find the class. Class c = Class.forName("InvokeMain"); // RECURSION System.out.println(c); // Create the array of Argument Types Class[] argTypes = { argv.getClass(), // array is Object! }; // Now find the method Method m = c.getMethod("main", argTypes); System.out.println(m); // Create the actual argument array Object passedArgv[] = { argv }; // Now invoke the method. m.invoke(null, passedArgv); } catch (Exception e) { System.err.println(e); } //- }
}
</source>
Sorts methods according to their name, number of parameters, and parameter types.
<source lang="java">
/**
* 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. */
import java.lang.reflect.Method; import java.util.ruparator; /**
* Sorts methods according to their name, number of parameters, and parameter * types. */
public class MethodComparator implements Comparator<Method> {
public int compare(Method m1, Method m2) { int val = m1.getName().rupareTo(m2.getName()); if (val == 0) { val = m1.getParameterTypes().length - m2.getParameterTypes().length; if (val == 0) { Class[] types1 = m1.getParameterTypes(); Class[] types2 = m2.getParameterTypes(); for (int i = 0; i < types1.length; i++) { val = types1[i].getName().rupareTo(types2[i].getName()); if (val != 0) { break; } } } } return val; }
}
</source>
The next example calls a class method with 2 arguments:
<source lang="java">
import java.lang.reflect.Method; public class Main{
static void invoke(String aClass, String aMethod, Class[] params, Object[] args) { try { Class c = Class.forName(aClass); Method m = c.getDeclaredMethod(aMethod, params); Object i = c.newInstance(); Object r = m.invoke(i, args); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { invoke("Class1", "say", new Class[] { String.class, String.class }, new Object[] { new String("Hello"), new String("World") }); }
} class Class1 {
public void say(String s1, String s2) { System.out.println(s1 + " " + s2); }
}
</source>
To get the calling method
<source lang="java">
public class Main {
public static void main(String args[]) { anotherLayout(); } public static void anotherLayout(){ new Main().doit(); } public void doit() { System.out.println( Thread.currentThread().getStackTrace()[3].getMethodName()); }
}
</source>
Using reflection to show all the methods of a class,
<source lang="java">
// : c10:ShowMethods.java // Using reflection to show all the methods of a class, // even if the methods are defined in the base class. // {Args: ShowMethods} // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.regex.Pattern; public class ShowMethods {
private static final String usage = "usage: \n" + "ShowMethods qualified.class.name\n" + "To show all methods in class or: \n" + "ShowMethods qualified.class.name word\n" + "To search for methods involving "word""; private static Pattern p = Pattern.rupile("\\w+\\."); public static void main(String[] args) { if (args.length < 1) { System.out.println(usage); System.exit(0); } int lines = 0; try { Class c = Class.forName(args[0]); Method[] m = c.getMethods(); Constructor[] ctor = c.getConstructors(); if (args.length == 1) { for (int i = 0; i < m.length; i++) System.out.println(p.matcher(m[i].toString()) .replaceAll("")); for (int i = 0; i < ctor.length; i++) System.out.println(p.matcher(ctor[i].toString()) .replaceAll("")); lines = m.length + ctor.length; } else { for (int i = 0; i < m.length; i++) if (m[i].toString().indexOf(args[1]) != -1) { System.out.println(p.matcher(m[i].toString()) .replaceAll("")); lines++; } for (int i = 0; i < ctor.length; i++) if (ctor[i].toString().indexOf(args[1]) != -1) { System.out.println(p.matcher(ctor[i].toString()) .replaceAll("")); lines++; } } } catch (ClassNotFoundException e) { System.out.println("No such class: " + e); } }
} ///:~
</source>