Java/Reflection/Field — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 06:01, 1 июня 2010
Содержание
- 1 All Fields Snippet
- 2 Checks whether the specified class contains a field matching the specified name.
- 3 Class Reflection: field information
- 4 Fetches all fields of all access types from the supplied class and super classes
- 5 Fetches the property descriptor for the named property of the supplied class
- 6 Field modifiers: isSynthetic, isEnumConstant
- 7 Field Reflection
- 8 Field with annotations
- 9 Find Field
- 10 Get all declared fields from a class
- 11 Get all object accessible public fields
- 12 Get a variable value from the variable name
- 13 Get field of a class object and set or get its value
- 14 Get fields of a class object
- 15 Getting the Field Objects of a Class Object: By obtaining a list of all declared fields.
- 16 Getting the Field Objects of a Class Object: By obtaining a list of all public fields, both declared and inherited.
- 17 Getting the Field Objects of a Class Object: By obtaining a particular Field object.
- 18 How to set public field objects
- 19 Object Reflection: get field value
- 20 Object Reflection: set value
- 21 Process bean properties getter by applying the JavaBean naming conventions.
- 22 Retrieving a Predefined Color by Name
- 23 Return a list of all fields (whatever access status, and on whatever superclass they were defined) that can be found on this class.
- 24 Set private field value
- 25 whether given field is a "public static final" constant
All Fields Snippet
/*
Java Reflection in Action
Ira R. Forman and Nate Forman
ISBN 1932394184
Publisher: Manning Publications Co.
*/
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
public class AllFieldsSnippet {
public static void main(String[] args) {
Object obj = new Object();
//start extract AllFieldsSnippet
Class cls = obj.getClass();
List accum = new LinkedList();
while (cls != null) {
Field[] f = cls.getDeclaredFields();
for (int i = 0; i < f.length; i++) {
accum.add(f[i]);
}
cls = cls.getSuperclass();
}
Field[] allFields = (Field[]) accum.toArray(new Field[accum.size()]);
//stop extract AllFieldsSnippet
}
}
Checks whether the specified class contains a field matching the specified name.
// $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 field matching the specified name.
*
* @param clazz The class to check.
* @param fieldName The field name.
*
* @return Returns <code>true</code> if the cass contains a field for the specified name, <code>
* false</code> otherwise.
*/
public static boolean containsField(Class<?> clazz, String fieldName) {
try {
clazz.getDeclaredField( fieldName );
return true;
}
catch ( NoSuchFieldException e ) {
return false;
}
}
}
Class Reflection: field information
/* 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.GridBagConstraints;
import java.lang.reflect.Field;
public class SampleField {
public static void main(String[] args) {
GridBagConstraints g = new GridBagConstraints();
printFieldNames(g);
}
static void printFieldNames(Object o) {
Class c = o.getClass();
Field[] publicFields = c.getFields();
for (int i = 0; i < publicFields.length; i++) {
String fieldName = publicFields[i].getName();
Class typeClass = publicFields[i].getType();
String fieldType = typeClass.getName();
System.out.println("Name: " + fieldName + ", Type: " + fieldType);
}
}
}
Fetches all fields of all access types from the supplied class and super classes
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);
}
/**
* <p>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:</p>
*
* <ul>
* <li>Uses the classes simple name instead of it"s fully qualified name.</li>
* <li>Only outputs attributes that are set to non-default values.</li>
*
* <p>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).</p>
*
* <p>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</p>
*
* <p>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.</p>
*
* @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;
}
}
Fetches the property descriptor for the named property of the supplied class
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);
}
/**
* <p>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:</p>
*
* <ul>
* <li>Uses the classes simple name instead of it"s fully qualified name.</li>
* <li>Only outputs attributes that are set to non-default values.</li>
*
* <p>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).</p>
*
* <p>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</p>
*
* <p>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.</p>
*
* @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;
}
}
Field modifiers: isSynthetic, isEnumConstant
/*
* 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.Field;
import java.lang.reflect.Modifier;
enum Spy {
BLACK, WHITE
}
public class FieldModifierSpy {
volatile int share;
int instance;
class Inner {
}
public static void main(String... args) {
try {
Class<?> c = Class.forName(args[0]);
int searchMods = 0x0;
for (int i = 1; i < args.length; i++) {
searchMods |= modifierFromString(args[i]);
}
Field[] flds = c.getDeclaredFields();
out.format("Fields in Class "%s" containing modifiers: %s%n", c
.getName(), Modifier.toString(searchMods));
boolean found = false;
for (Field f : flds) {
int foundMods = f.getModifiers();
// Require all of the requested modifiers to be present
if ((foundMods & searchMods) == searchMods) {
out.format("%-8s [ synthetic=%-5b enum_constant=%-5b ]%n", f
.getName(), f.isSynthetic(), f.isEnumConstant());
found = true;
}
}
if (!found) {
out.format("No matching fields%n");
}
// production code should handle this exception more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
private static int modifierFromString(String s) {
int m = 0x0;
if ("public".equals(s))
m |= Modifier.PUBLIC;
else if ("protected".equals(s))
m |= Modifier.PROTECTED;
else if ("private".equals(s))
m |= Modifier.PRIVATE;
else if ("static".equals(s))
m |= Modifier.STATIC;
else if ("final".equals(s))
m |= Modifier.FINAL;
else if ("transient".equals(s))
m |= Modifier.TRANSIENT;
else if ("volatile".equals(s))
m |= Modifier.VOLATILE;
return m;
}
}
Field Reflection
import java.lang.reflect.Field;
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:");
printFields(cl);
System.out.println();
} catch (ClassNotFoundException e) {
System.out.println("Class not found.");
}
}
public static void printFields(Class cl) {
Field[] fields = cl.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
Class type = f.getType();
String name = f.getName();
System.out.print(Modifier.toString(f.getModifiers()));
System.out.println(" " + type.getName() + " " + name + ";");
}
}
}
Field with annotations
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
public class DataBeanTest {
public static void main(String[] args) {
Class d = DataBean.class;
Field fs[] = d.getFields();
for (Field f : fs) {
System.out.println(f);
Annotation a = f.getAnnotation(DataField.class);
if (a != null) {
System.out.println(f.getName());
}
}
}
}
class DataBean {
@DataField
public String name;
@DataField
public String data;
public String description;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface DataField {
}
Find Field
//
//$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 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);
}
}
}
Get all declared fields from a class
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("\nFields:");
Field fields[] = c.getDeclaredFields();
for (Field fld : fields)
System.out.println(" " + fld);
}
}
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);
}
}
Get all object accessible public fields
import java.lang.reflect.Field;
import java.util.Date;
public class Main {
public static void main(String[] args) throws Exception {
GetFields object = new GetFields();
Class clazz = object.getClass();
// Get all object accessible public fields.
Field[] fields = clazz.getFields();
System.out.println("Number of fields = " + fields.length);
for (Field field : fields) {
System.out.println("Field name = " + field.getName());
System.out.println("Field type = " + field.getType().getName());
}
Field field = clazz.getField("id");
System.out.println("Field name = " + field.getName());
System.out.println("Field type = " + field.getType().getName());
}
}
class GetFields {
public Long id;
protected String name;
private Date birthDate;
Double weight;
}
Get a variable value from the variable name
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws Exception {
Object clazz = new TestClass();
String lookingForValue = "firstValue";
Field field = clazz.getClass().getField(lookingForValue);
Class clazzType = field.getType();
if (clazzType.toString().equals("double"))
System.out.println(field.getDouble(clazz));
else if (clazzType.toString().equals("int"))
System.out.println(field.getInt(clazz));
//System.out.println(field.get(clazz));
}
}
class TestClass {
public double firstValue = 3.14;
}
Get field of a class object and set or get its value
import java.lang.reflect.Field;
import java.util.Date;
public class Main {
public static void main(String[] args) throws Exception {
Bean demo = new Bean();
Class clazz = demo.getClass();
Field field = clazz.getField("id");
field.set(demo, new Long(10));
Object value = field.get(demo);
System.out.println("Value = " + value);
field = clazz.getField("now");
field.set(null, new Date());
value = field.get(null);
System.out.println("Value = " + value);
}
}
class Bean {
public static Date now;
public Long id;
public String name;
}
Get fields of a class object
import java.lang.reflect.Field;
import java.util.Date;
public class Main {
public static void main(String[] args) throws Exception {
GetFields object = new GetFields();
Class clazz = object.getClass();
// Get all object fields including public, protected, package and private
// access fields.
Field[] fields = clazz.getDeclaredFields();
System.out.println("Number of fields = " + fields.length);
for (Field field : fields) {
System.out.println("Field name = " + field.getName());
System.out.println("Field type = " + field.getType().getName());
}
}
}
class GetFields {
public Long id;
protected String name;
private Date birthDate;
Double weight;
}
Getting the Field Objects of a Class Object: By obtaining a list of all declared fields.
import java.lang.reflect.Field;
public class Main {
public static void main(String[] argv) throws Exception {
Class cls = java.awt.Point.class;
Field[] fields = cls.getDeclaredFields();
}
}
Getting the Field Objects of a Class Object: By obtaining a list of all public fields, both declared and inherited.
import java.lang.reflect.Field;
public class Main {
public static void main(String[] argv) throws Exception {
Class cls = java.awt.Point.class;
Field[] fields = cls.getFields();
for (int i = 0; i < fields.length; i++) {
Class type = fields[i].getType();
System.out.println(fields[i]);
}
}
}
Getting the Field Objects of a Class Object: By obtaining a particular Field object.
import java.lang.reflect.Field;
public class Main {
public static void main(String[] argv) throws Exception {
Class cls = java.awt.Point.class;
Field field = cls.getField("x");
System.out.println(field);
}
}
How to set public field objects
/*
Before: [a=21.25, b=54.5, c=5665, d=2043, e=3121, f=1019]
After: [a=21.25, b=54.5, c=0, d=0, e=3121, f=1019]
*/
/*
*
* 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.Field;
/**
* Demonstrates how to set public field objects.
*
* @author
* @version $Revision: 1.3 $
*/
public class FieldModification {
/**
* Sets all int fields in an object to 0.
*
* @param obj The object to operate on.
*
* @throws RuntimeException If there is a reflection problem.
*/
public static void initPublicIntFields(final Object obj) {
try {
Field[] fields = obj.getClass()
.getFields();
for (int idx = 0; idx < fields.length; idx++) {
if (fields[idx].getType() == int.class) {
fields[idx].setInt(obj, 0);
}
}
} catch (final IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
/**
* Sets all int fields in an object to 0.
*
* @param obj The object to operate on.
*
* @throws RuntimeException If there is a reflection problem.
*/
public static void initPublicIntFields2(final Object obj) {
try {
final Integer value = new Integer(0);
Field[] fields = obj.getClass()
.getFields();
for (int idx = 0; idx < fields.length; idx++) {
if (fields[idx].getType() == int.class) {
fields[idx].set(obj, value);
}
}
} catch (final IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
/**
* Demo Method.
*
* @param args Command line arguments.
*/
public static final void main(final String[] args) {
SomeNumbers value = new SomeNumbers();
System.out.println("Before: " + value);
initPublicIntFields(value);
System.out.println("After: " + value);
}
}
class SomeNumbers {
/** A demo double. */
public double a = 21.25d;
/** A demo float. */
public float b = 54.5f;
/** A Demo int */
public int c = 5665;
/** Another demo int. */
public int d = 2043;
/** Another demo int. */
protected int e = 3121;
/** Another demo int. */
private int f = 1019;
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return new String("[a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + ", e=" + e
+ ", f=" + f + "]");
}
}
Object Reflection: get field value
/* 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.Rectangle;
import java.lang.reflect.Field;
public class SampleGet {
public static void main(String[] args) {
Rectangle r = new Rectangle(100, 325);
printHeight(r);
}
static void printHeight(Rectangle r) {
Field heightField;
Integer heightValue;
Class c = r.getClass();
try {
heightField = c.getField("height");
heightValue = (Integer) heightField.get(r);
System.out.println("Height: " + heightValue.toString());
} catch (NoSuchFieldException e) {
System.out.println(e);
} catch (SecurityException e) {
System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
}
}
}
Object Reflection: set value
/* 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.Rectangle;
import java.lang.reflect.Field;
public class SampleSet {
public static void main(String[] args) {
Rectangle r = new Rectangle(100, 20);
System.out.println("original: " + r.toString());
modifyWidth(r, new Integer(300));
System.out.println("modified: " + r.toString());
}
static void modifyWidth(Rectangle r, Integer widthParam) {
Field widthField;
Integer widthValue;
Class c = r.getClass();
try {
widthField = c.getField("width");
widthField.set(r, widthParam);
} catch (NoSuchFieldException e) {
System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
}
}
}
Process bean properties getter by applying the JavaBean naming conventions.
// $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 {
/**
* Process bean properties getter by applying the JavaBean naming conventions.
*
* @param member the member for which to get the property name.
*
* @return The bean method name with the "is" or "get" prefix stripped off, <code>null</code>
* the method name id not according to the JavaBeans standard.
*/
public static String getPropertyName(Member member) {
String name = null;
if ( member instanceof Field ) {
name = member.getName();
}
if ( member instanceof Method ) {
String methodName = member.getName();
if ( methodName.startsWith( "is" ) ) {
name = Introspector.decapitalize( methodName.substring( 2 ) );
}
else if ( methodName.startsWith( "get" ) ) {
name = Introspector.decapitalize( methodName.substring( 3 ) );
}
}
return name;
}
}
Retrieving a Predefined Color by Name
import java.awt.Color;
import java.lang.reflect.Field;
public class Main {
public static void main(String[] argv) throws Exception {
System.out.println(getColor("blue"));
}
public static Color getColor(String colorName) {
try {
Field field = Class.forName("java.awt.Color").getField(colorName);
return (Color) field.get(null);
} catch (Exception e) {
return null;
}
}
}
Return a list of all fields (whatever access status, and on whatever superclass they were defined) that can be found on this class.
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
/*
* Copyright 2005 Joe Walker
*
* 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.
*/
/**
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class Main {
/**
* Return a list of all fields (whatever access status, and on whatever
* superclass they were defined) that can be found on this class.
* <p>This is like a union of {@link Class#getDeclaredFields()} which
* ignores and super-classes, and {@link Class#getFields()} which ignored
* non-public fields
* @param clazz The class to introspect
* @return The complete list of fields
*/
public static Field[] getAllFields(Class<?> clazz)
{
List<Class<?>> classes = getAllSuperclasses(clazz);
classes.add(clazz);
return getAllFields(classes);
}
/**
* As {@link #getAllFields(Class)} but acts on a list of {@link Class}s and
* uses only {@link Class#getDeclaredFields()}.
* @param classes The list of classes to reflect on
* @return The complete list of fields
*/
private static Field[] getAllFields(List<Class<?>> classes)
{
Set<Field> fields = new HashSet<Field>();
for (Class<?> clazz : classes)
{
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
}
return fields.toArray(new Field[fields.size()]);
}
/**
* Return a List of super-classes for the given class.
* @param clazz the class to look up
* @return the List of super-classes in order going up from this one
*/
public static List<Class<?>> getAllSuperclasses(Class<?> clazz)
{
List<Class<?>> classes = new ArrayList<Class<?>>();
Class<?> superclass = clazz.getSuperclass();
while (superclass != null)
{
classes.add(superclass);
superclass = superclass.getSuperclass();
}
return classes;
}
}
Set private field value
/*
* 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.Field;
public class FieldTroubleToo {
public final boolean b = true;
public static void main(String... args) {
FieldTroubleToo ft = new FieldTroubleToo();
try {
Class<?> c = ft.getClass();
Field f = c.getDeclaredField("b");
// f.setAccessible(true); // solution
f.setBoolean(ft, Boolean.FALSE); // IllegalAccessException
// production code should handle these exceptions more gracefully
} catch (NoSuchFieldException x) {
x.printStackTrace();
} catch (IllegalArgumentException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}
whether given field is a "public static final" constant
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* Simple utility class for working with the reflection API and handling
* reflection exceptions.
*
* <p>Only intended for internal use.
*
* @author Juergen Hoeller
* @author Rob Harrop
* @author Rod Johnson
* @author Costin Leau
* @since 1.2.2
*/
public abstract class ReflectionUtils {
/**
* Determine whether the given field is a "public static final" constant.
* @param field the field to check
*/
public static boolean isPublicStaticFinal(Field field) {
int modifiers = field.getModifiers();
return (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers));
}
}