Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 2013-2014 sagyf Yang. The Four Group.
   */
  package com.github.sog.kit.common;
  
  
 import java.util.Map;

A wrapper for an java.lang.Object or java.lang.Class upon which reflective calls can be made.

An example of using Reflect is

 // Static import all reflection methods to decrease verbosity
 import static org.joor.Reflect.*;
 

// Wrap an Object / Class / class name with the on() method: on("java.lang.String") // Invoke constructors using the create() method: .create("Hello World") // Invoke methods using the call() method: .call("toString") // Retrieve the wrapped object

Author(s):
Lukas Eder
 
 public class Reflect {
    
The wrapped object
 
     private final Object object;
    
A flag indicating whether the wrapped object is a java.lang.Class (for accessing static fields and methods), or any other type of java.lang.Object (for accessing instance fields and methods).
 
     private final boolean isClass;
 
     private Reflect(Class<?> type) {
         this. = type;
         this. = true;
     }
 
     // ---------------------------------------------------------------------
     // Static API used as entrance points to the fluent API
     // ---------------------------------------------------------------------
 
     private Reflect(Object object) {
         this. = object;
         this. = false;
     }

    
Dynamic version of instanceof.

Parameters:
o object to match
target target class
Returns:
true if object is an instance of target class
 
     public static boolean isInstanceOf(Object oClass target) {
         return isSubclass(o.getClass(), target);
     }

    
Determines if first class match the destination and simulates kind of instanceof. All subclasses and interface of first class are examined against second class. Method is not symmetric.
 
     public static boolean isSubclass(Class thisClassClass target) {
         if (target.isInterface() != false) {
             return isInterfaceImpl(thisClasstarget);
         }
         for (Class x = thisClassx != nullx = x.getSuperclass()) {
             if (x == target) {
                 return true;
             }
         }
         return false;
     }

    
Returns true if provided class is interface implementation.
 
     public static boolean isInterfaceImpl(Class thisClassClass targetInterface) {
         for (Class x = thisClassx != nullx = x.getSuperclass()) {
             Class[] interfaces = x.getInterfaces();
             for (Class i : interfaces) {
                 if (i == targetInterface) {
                     return true;
                 }
                if (isInterfaceImpl(itargetInterface)) {
                    return true;
                }
            }
        }
        return false;
    }
    // ---------------------------------------------------------------------
    // Members
    // ---------------------------------------------------------------------

    
Wrap a class name.

This is the same as calling on(Class.forName(name))

Parameters:
name A fully qualified class name
Returns:
A wrapped class object, to be used for further reflection.
Throws:
ReflectException If any reflection exception occurred.
See also:
on(java.lang.Class)
    public static Reflect on(String namethrows ReflectException {
        return on(forName(name));
    }

    
Wrap a class.

Use this when you want to access static fields and methods on a java.lang.Class object, or as a basis for constructing objects of that class using create(java.lang.Object[])

Parameters:
clazz The class to be wrapped
Returns:
A wrapped class object, to be used for further reflection.
    public static Reflect on(Class<?> clazz) {
        return new Reflect(clazz);
    }
    // ---------------------------------------------------------------------
    // Constructors
    // ---------------------------------------------------------------------

    
Wrap an object.

Use this when you want to access instance fields and methods on any java.lang.Object

Parameters:
object The object to be wrapped
Returns:
A wrapped object, to be used for further reflection.
    public static Reflect on(Object object) {
        return new Reflect(object);
    }

    
Conveniently render an java.lang.reflect.AccessibleObject accessible

Parameters:
accessible The object to render accessible
Returns:
The argument object rendered accessible
    public static <T extends AccessibleObject> T accessible(T accessible) {
        if (accessible == null) {
            return null;
        }
        if (!accessible.isAccessible()) {
            accessible.setAccessible(true);
        }
        return accessible;
    }
    // ---------------------------------------------------------------------
    // Fluent Reflection API
    // ---------------------------------------------------------------------

    
Get the POJO property name of an getter/setter
    private static String property(String string) {
        int length = string.length();
        if (length == 0) {
            return "";
        } else if (length == 1) {
            return string.toLowerCase();
        } else {
            return string.substring(0, 1).toLowerCase() + string.substring(1);
        }
    }

    
Wrap an object created from a constructor
    private static Reflect on(Constructor<?> constructorObject... argsthrows ReflectException {
        try {
            return on(accessible(constructor).newInstance(args));
        } catch (Exception e) {
            throw new ReflectException(e);
        }
    }

    
Wrap an object returned from a method
    private static Reflect on(Method methodObject objectObject... argsthrows ReflectException {
        try {
            accessible(method);
            if (method.getReturnType() == void.class) {
                method.invoke(objectargs);
                return on(object);
            } else {
                return on(method.invoke(objectargs));
            }
        } catch (Exception e) {
            throw new ReflectException(e);
        }
    }

    
Unwrap an object
    private static Object unwrap(Object object) {
        if (object instanceof Reflect) {
            return ((Reflectobject).get();
        }
        return object;
    }

    
Get an array of types for an array of objects

    private static Class<?>[] types(Object... values) {
        if (values == null) {
            return new Class[0];
        }
        Class<?>[] result = new Class[values.length];
        for (int i = 0; i < values.lengthi++) {
            Object value = values[i];
            result[i] = value == null ? Object.class : value.getClass();
        }
        return result;
    }

    
    private static Class<?> forName(String namethrows ReflectException {
        try {
            return Class.forName(name);
        } catch (Exception e) {
            throw new ReflectException(e);
        }
    }

    
Get a wrapper type for a primitive type, or the argument type itself, if it is not a primitive type.
    public static Class<?> wrapper(Class<?> type) {
        if (type == null) {
            return null;
        } else if (type.isPrimitive()) {
            if (boolean.class == type) {
                return Boolean.class;
            } else if (int.class == type) {
                return Integer.class;
            } else if (long.class == type) {
                return Long.class;
            } else if (short.class == type) {
                return Short.class;
            } else if (byte.class == type) {
                return Byte.class;
            } else if (double.class == type) {
                return Double.class;
            } else if (float.class == type) {
                return Float.class;
            } else if (char.class == type) {
                return Character.class;
            } else if (void.class == type) {
                return Void.class;
            }
        }
        return type;
    }

    
Get the wrapped object

Parameters:
<T> A convenience generic parameter for automatic unsafe casting
    @SuppressWarnings("unchecked")
    public <T> T get() {
        return (T) ;
    }

    
Set a field value.

This is roughly equivalent to java.lang.reflect.Field.set(java.lang.Object,java.lang.Object). If the wrapped object is a java.lang.Class, then this will set a value to a static member field. If the wrapped object is any other java.lang.Object, then this will set a value to an instance member field.

Parameters:
name The field name
value The new field value
Returns:
The same wrapped object, to be used for further reflection.
Throws:
ReflectException If any reflection exception occurred.
    public Reflect set(String nameObject valuethrows ReflectException {
        try {
            // Try setting a public field
            Field field = type().getField(name);
            field.set(unwrap(value));
            return this;
        } catch (Exception e1) {
            // Try again, setting a non-public field
            try {
                accessible(type().getDeclaredField(name)).set(unwrap(value));
                return this;
            } catch (Exception e2) {
                throw new ReflectException(e2);
            }
        }
    }

    
Get a field value.

This is roughly equivalent to java.lang.reflect.Field.get(java.lang.Object). If the wrapped object is a java.lang.Class, then this will get a value from a static member field. If the wrapped object is any other java.lang.Object, then this will get a value from an instance member field.

If you want to "navigate" to a wrapped version of the field, use field(java.lang.String) instead.

Parameters:
name The field name
Returns:
The field value
Throws:
ReflectException If any reflection exception occurred.
See also:
field(java.lang.String)
    public <T> T get(String namethrows ReflectException {
        return field(name).get();
    }

    
TODO:(简单描述方法作用).

Parameters:
clazz
name
Returns:
Throws:
java.lang.NoSuchFieldException
Author(s):
kid create 2013-8-29
    public Field getDeclaredField(Class<?> clazzString namethrows NoSuchFieldException {
        Field field = null;
        while (clazz != Object.class) {
            try {
                field = clazz.getDeclaredField(name);
                if (field != null)
                    break;
            } catch (Exception e) {
                clazz = clazz.getSuperclass();
            }
        }
        if (field == null) {
            throw new NoSuchFieldException("name is not found");
        }
        return field;
    }

    
Get a wrapped field.

This is roughly equivalent to java.lang.reflect.Field.get(java.lang.Object). If the wrapped object is a java.lang.Class, then this will wrap a static member field. If the wrapped object is any other java.lang.Object, then this wrap an instance member field.

Parameters:
name The field name
Returns:
The wrapped field
Throws:
ReflectException If any reflection exception occurred.
    public Reflect field(String namethrows ReflectException {
        try {
            // Try getting a public field
            Field field = type().getField(name);
            return on(field.get());
        } catch (Exception e1) {
            // Try again, getting a non-public field
            try {
                return on(accessible(getDeclaredField(type(), name)).get());
            } catch (Exception e2) {
                throw new ReflectException(e2);
            }
        }
    }

    
Get a Map containing field names and wrapped values for the fields' values.

If the wrapped object is a java.lang.Class, then this will return static fields. If the wrapped object is any other java.lang.Object, then this will return instance fields.

These two calls are equivalent

 on(object).field("myField");
 on(object).fields().get("myField");
 

Returns:
A map containing field names and wrapped values.
    public Map<StringReflectfields() {
        Map<StringReflectresult = Maps.newLinkedHashMap();
        for (Field field : type().getFields()) {
            if (! ^ Modifier.isStatic(field.getModifiers())) {
                String name = field.getName();
                result.put(namefield(name));
            }
        }
        return result;
    }

    
Call a method by its name.

This is a convenience method for calling call(name, new Object[0])

Parameters:
name The method name
Returns:
The wrapped method result or the same wrapped object if the method returns void, to be used for further reflection.
Throws:
ReflectException If any reflection exception occurred.
See also:
call(java.lang.String,java.lang.Object[])
    public Reflect call(String namethrows ReflectException {
        return call(namenew Object[0]);
    }

    
Call a method by its name.

This is roughly equivalent to java.lang.reflect.Method.invoke(java.lang.Object,java.lang.Object[]). If the wrapped object is a java.lang.Class, then this will invoke a static method. If the wrapped object is any other java.lang.Object, then this will invoke an instance method.

Just like java.lang.reflect.Method.invoke(java.lang.Object,java.lang.Object[]), this will try to wrap primitive types or unwrap primitive type wrappers if applicable. If several methods are applicable, by that rule, the first one encountered is called. i.e. when calling

 on(...).call("method", 1, 1);
 
The first of the following methods will be called:
 public void method(int param1, Integer param2);
 public void method(Integer param1, int param2);
 public void method(Number param1, Number param2);
 public void method(Number param1, Object param2);
 public void method(int param1, Object param2);
 

The best matching method is searched for with the following strategy:

  1. public method with exact signature match in class hierarchy
  2. non-public method with exact signature match on declaring class
  3. public method with similar signature in class hierarchy
  4. non-public method with similar signature on declaring class

Parameters:
name The method name
args The method arguments
Returns:
The wrapped method result or the same wrapped object if the method returns void, to be used for further reflection.
Throws:
ReflectException If any reflection exception occurred.
    public Reflect call(String nameObject... argsthrows ReflectException {
        Class<?>[] types = types(args);
        // Try invoking the "canonical" method, i.e. the one with exact
        // matching argument types
        try {
            Method method = exactMethod(nametypes);
            return on(methodargs);
        }
        // If there is no exact match, try to find a method that has a "similar"
        // signature if primitive argument types are converted to their wrappers
        catch (NoSuchMethodException e) {
            try {
                Method method = similarMethod(nametypes);
                return on(methodargs);
            } catch (NoSuchMethodException e1) {
                throw new ReflectException(e1);
            }
        }
    }
    // ---------------------------------------------------------------------
    // Object API
    // ---------------------------------------------------------------------

    
Searches a method with the exact same signature as desired.

If a public method is found in the class hierarchy, this method is returned. Otherwise a private method with the exact same signature is returned. If no exact match could be found, we let the NoSuchMethodException pass through.

    private Method exactMethod(String nameClass<?>[] typesthrows NoSuchMethodException {
        final Class<?> type = type();
        // first priority: find a public method with exact signature match in class hierarchy
        try {
            return type.getMethod(nametypes);
        }
        // second priority: find a private method with exact signature match on declaring class
        catch (NoSuchMethodException e) {
            return type.getDeclaredMethod(nametypes);
        }
    }

    
Searches a method with a similar signature as desired using isSimilarSignature(java.lang.reflect.Method,java.lang.String,java.lang.Class[]).

First public methods are searched in the class hierarchy, then private methods on the declaring class. If a method could be found, it is returned, otherwise a NoSuchMethodException is thrown.

    private Method similarMethod(String nameClass<?>[] typesthrows NoSuchMethodException {
        final Class<?> type = type();
        // first priority: find a public method with a "similar" signature in class hierarchy
        // similar interpreted in when primitive argument types are converted to their wrappers
        for (Method method : type.getMethods()) {
            if (isSimilarSignature(methodnametypes)) {
                return method;
            }
        }
        // second priority: find a non-public method with a "similar" signature on declaring class
        for (Method method : type.getDeclaredMethods()) {
            if (isSimilarSignature(methodnametypes)) {
                return method;
            }
        }
        throw new NoSuchMethodException("No similar method " + name + " with params " + Arrays.toString(types)
                + " could be found on type " + type() + ".");
    }

    
Determines if a method has a "similar" signature, especially if wrapping primitive argument types would result in an exactly matching signature.
    private boolean isSimilarSignature(Method possiblyMatchingMethodString desiredMethodName,
                                       Class<?>[] desiredParamTypes) {
        return possiblyMatchingMethod.getName().equals(desiredMethodName)
                && match(possiblyMatchingMethod.getParameterTypes(), desiredParamTypes);
    }

    
Call a constructor.

This is a convenience method for calling create(new Object[0])

Returns:
The wrapped new object, to be used for further reflection.
Throws:
ReflectException If any reflection exception occurred.
See also:
create(java.lang.Object[])
    public Reflect create() throws ReflectException {
        return create(new Object[0]);
    }
    // ---------------------------------------------------------------------
    // Utility methods
    // ---------------------------------------------------------------------

    
Call a constructor.

This is roughly equivalent to java.lang.reflect.Constructor.newInstance(java.lang.Object[]). If the wrapped object is a java.lang.Class, then this will create a new object of that class. If the wrapped object is any other java.lang.Object, then this will create a new object of the same type.

Just like java.lang.reflect.Constructor.newInstance(java.lang.Object[]), this will try to wrap primitive types or unwrap primitive type wrappers if applicable. If several constructors are applicable, by that rule, the first one encountered is called. i.e. when calling

 on(C.class).create(1, 1);
 
The first of the following constructors will be applied:
 public C(int param1, Integer param2);
 public C(Integer param1, int param2);
 public C(Number param1, Number param2);
 public C(Number param1, Object param2);
 public C(int param1, Object param2);
 

Parameters:
args The constructor arguments
Returns:
The wrapped new object, to be used for further reflection.
Throws:
ReflectException If any reflection exception occurred.
    public Reflect create(Object... argsthrows ReflectException {
        Class<?>[] types = types(args);
        // Try invoking the "canonical" constructor, i.e. the one with exact
        // matching argument types
        try {
            Constructor<?> constructor = type().getDeclaredConstructor(types);
            return on(constructorargs);
        }
        // If there is no exact match, try to find one that has a "similar"
        // signature if primitive argument types are converted to their wrappers
        catch (NoSuchMethodException e) {
            for (Constructor<?> constructor : type().getConstructors()) {
                if (match(constructor.getParameterTypes(), types)) {
                    return on(constructorargs);
                }
            }
            throw new ReflectException(e);
        }
    }

    
Create a proxy for the wrapped object allowing to typesafely invoke methods on it using a custom interface

Parameters:
proxyType The interface type that is implemented by the proxy
Returns:
A proxy for the wrapped object
    @SuppressWarnings("unchecked")
    public <P> P as(Class<P> proxyType) {
        final boolean isMap = ( instanceof Map);
        final InvocationHandler handler = new InvocationHandler() {
            @SuppressWarnings("null")
            @Override
            public Object invoke(Object proxyMethod methodObject[] argsthrows Throwable {
                String name = method.getName();
                // Actual method name matches always come first
                try {
                    return on().call(nameargs).get();
                }
                // [#14] Simulate POJO behaviour on wrapped map objects
                catch (ReflectException e) {
                    if (isMap) {
                        Map<StringObjectmap = (Map<StringObject>) ;
                        int length = (args == null ? 0 : args.length);
                        if (length == 0 && name.startsWith("get")) {
                            return map.get(property(name.substring(3)));
                        } else if (length == 0 && name.startsWith("is")) {
                            return map.get(property(name.substring(2)));
                        } else if (length == 1 && name.startsWith("set")) {
                            map.put(property(name.substring(3)), args[0]);
                            return null;
                        }
                    }
                    throw e;
                }
            }
        };
        return (P) Proxy.newProxyInstance(proxyType.getClassLoader(), new Class[]{proxyType}, handler);
    }

    
Check whether two arrays of types match, converting primitive types to their corresponding wrappers.
    private boolean match(Class<?>[] declaredTypesClass<?>[] actualTypes) {
        if (declaredTypes.length == actualTypes.length) {
            for (int i = 0; i < actualTypes.lengthi++) {
                if (!wrapper(declaredTypes[i]).isAssignableFrom(wrapper(actualTypes[i]))) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

    
    @Override
    public int hashCode() {
        return .hashCode();
    }

    
    @Override
    public boolean equals(Object obj) {
        return obj instanceof Reflect && .equals(((Reflectobj).get());
    }

    
    @Override
    public String toString() {
        return .toString();
    }

    
Get the type of the wrapped object.

    public Class<?> type() {
        if () {
            return (Class<?>) ;
        } else {
            return .getClass();
        }
    }
New to GrepCode? Check out our FAQ X