Java tutorial
/* * Copyright 2007-2012 Jiemamy Project and the Others. * * This file is part of Jiemamy. * * 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. */ package org.jiemamy.utils.reflect; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.commons.lang.Validate; /** * {@link Method}? * * @version $Id$ * @author j5ik2o */ public final class MethodUtil { /** ? */ private static final int BUFF_SIZE = 100; private static final Method IS_BRIDGE_METHOD = getIsBridgeMethod(); private static final Method IS_SYNTHETIC_METHOD = getIsSyntheticMethod(); /** {@link #getElementTypeOfCollectionFromParameterType(Method, int)}??? */ private static final Method GET_ELEMENT_TYPE_OF_COLLECTION_FROM_PARAMETER_METHOD = getElementTypeFromParameterMethod( "Collection"); /** {@link #getElementTypeOfCollectionFromReturnType(Method)}??? */ private static final Method GET_ELEMENT_TYPE_OF_COLLECTION_FROM_RETURN_METHOD = getElementTypeFromReturnMethod( "Collection"); /** {@link #getElementTypeOfListFromParameterType(Method, int)}??? */ private static final Method GET_ELEMENT_TYPE_OF_LIST_FROM_PARAMETER_METHOD = getElementTypeFromParameterMethod( "List"); /** {@link #getElementTypeOfListFromReturnType(Method)}??? */ private static final Method GET_ELEMENT_TYPE_OF_LIST_FROM_RETURN_METHOD = getElementTypeFromReturnMethod( "List"); /** {@link #getElementTypeOfSetFromParameterType(Method, int)}??? */ private static final Method GET_ELEMENT_TYPE_OF_SET_FROM_PARAMETER_METHOD = getElementTypeFromParameterMethod( "Set"); /** {@link #getElementTypeOfSetFromReturnType(Method)}??? */ private static final Method GET_ELEMENT_TYPE_OF_SET_FROM_RETURN_METHOD = getElementTypeFromReturnMethod("Set"); /** * ? (??)???? * * @param method * @param position ???????? * @return ????????????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? */ public static Class<?> getElementTypeOfCollectionFromParameterType(Method method, int position) throws IllegalAccessException, InvocationTargetException { return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_COLLECTION_FROM_PARAMETER_METHOD, null, new Object[] { method, Integer.valueOf(position) }); } /** * ??????????????? * * @param method * @return ????????????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? */ public static Class<?> getElementTypeOfCollectionFromReturnType(Method method) throws IllegalAccessException, InvocationTargetException { return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_COLLECTION_FROM_RETURN_METHOD, null, new Object[] { method }); } /** * ? (??) ???? * * @param method * @param position ???????? * @return ????????????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? */ public static Class<?> getElementTypeOfListFromParameterType(Method method, int position) throws IllegalAccessException, InvocationTargetException { return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_LIST_FROM_PARAMETER_METHOD, null, new Object[] { method, Integer.valueOf(position) }); } /** * ??????????????? * * @param method * @return ????????????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? */ public static Class<?> getElementTypeOfListFromReturnType(Method method) throws IllegalAccessException, InvocationTargetException { return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_LIST_FROM_RETURN_METHOD, null, new Object[] { method }); } /** * ? (??) ???? * * @param method * @param position ???????? * @return ????????????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? */ public static Class<?> getElementTypeOfSetFromParameterType(Method method, int position) throws IllegalAccessException, InvocationTargetException { return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_SET_FROM_PARAMETER_METHOD, null, new Object[] { method, Integer.valueOf(position) }); } /** * ??????????????? * * @param method * @return ????????????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? */ public static Class<?> getElementTypeOfSetFromReturnType(Method method) throws IllegalAccessException, InvocationTargetException { if (GET_ELEMENT_TYPE_OF_SET_FROM_RETURN_METHOD == null) { return null; } return (Class<?>) invoke(GET_ELEMENT_TYPE_OF_SET_FROM_RETURN_METHOD, null, new Object[] { method }); } /** * ??? * * <p> {@code getSignature(java.lang.String, java.lang.Class[])}</p> * * @param methodName ?? * @param argTypes * @return ? */ public static String getSignature(String methodName, Class<?>[] argTypes) { StringBuilder sb = new StringBuilder(BUFF_SIZE); sb.append(methodName); sb.append("("); if (argTypes != null) { for (int i = 0; i < argTypes.length; ++i) { if (i > 0) { sb.append(", "); } sb.append(argTypes[i].getName()); } } sb.append(")"); return sb.toString(); } /** * ??? * * @param methodName ?? * @param methodArgs ? * @return ? */ public static String getSignature(String methodName, Object[] methodArgs) { StringBuilder sb = new StringBuilder(BUFF_SIZE); sb.append(methodName); sb.append("("); if (methodArgs != null) { for (int i = 0; i < methodArgs.length; ++i) { if (i > 0) { sb.append(", "); } if (methodArgs[i] != null) { sb.append(methodArgs[i].getClass().getName()); } else { sb.append("null"); } } } sb.append(")"); return sb.toString(); } /** * {@link Method#invoke(Object, Object[])}??? * * @param method * @param target * @param args * @return * @throws IllegalAccessException ??????? * @throws IllegalArgumentException ??????? * @throws InvocationTargetException ??? * @see Method#invoke(Object, Object[]) * @throws IllegalArgumentException {@code method}?{@code null}??? */ public static Object invoke(Method method, Object target, Object[] args) throws IllegalAccessException, InvocationTargetException { Validate.notNull(method); try { return method.invoke(target, args); } catch (InvocationTargetException ex) { Throwable t = ex.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } if (t instanceof Error) { throw (Error) t; } throw ex; } } /** * ?????? * * @param method {@link Method} * @return ???? * @throws InvocationTargetException ??? * @throws IllegalAccessException ?? * @throws IllegalArgumentException ??????? */ public static boolean isBridgeMethod(Method method) throws IllegalAccessException, InvocationTargetException { if (IS_BRIDGE_METHOD == null) { return false; } return ((Boolean) invoke(IS_BRIDGE_METHOD, method, null)).booleanValue(); } /** * {@link #equals(Object)}?????? * * @param method {@link Method} * @return equals???? */ public static boolean isEqualsMethod(Method method) { return method != null && method.getName().equals("equals") && method.getReturnType() == boolean.class && method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == Object.class; } /** * {@link #hashCode()}?????? * * @param method {@link Method} * @return hashCode???? */ public static boolean isHashCodeMethod(Method method) { return method != null && method.getName().equals("hashCode") && method.getReturnType() == int.class && method.getParameterTypes().length == 0; } /** * ???????? * * @param method {@link Method} * @return ?????? * @throws InvocationTargetException ??? * @throws IllegalAccessException ?? * @throws IllegalArgumentException ??????? */ public static boolean isSyntheticMethod(Method method) throws IllegalAccessException, InvocationTargetException { if (IS_SYNTHETIC_METHOD == null) { return false; } return ((Boolean) invoke(IS_SYNTHETIC_METHOD, method, null)).booleanValue(); } /** * {@link #toString()}?????? * * @param method {@link Method} * @return toString???? */ public static boolean isToStringMethod(Method method) { return method != null && method.getName().equals("toString") && method.getReturnType() == String.class && method.getParameterTypes().length == 0; } /** * {@code ReflectionUtil#getElementTypeOf<var>Xxx</var>FromParameter}?{@link Method}?? * * @param type ??????? * @return {@link Method} */ protected static Method getElementTypeFromParameterMethod(String type) { try { Class<?> reflectionUtilClass = ReflectionUtil.class; return reflectionUtilClass.getMethod("getElementTypeOf" + type + "FromParameterType", new Class[] { Method.class, int.class }); } catch (Throwable ignore) { // ignore } return null; } /** * {@code ReflectionUtil#getElementTypeOf<var>Xxx</var>FromReturn}?{@link Method}?? * * @param type ??????? * @return {@link Method} */ protected static Method getElementTypeFromReturnMethod(String type) { try { Class<?> reflectionUtilClass = ReflectionUtil.class; return reflectionUtilClass.getMethod("getElementTypeOf" + type + "FromReturnType", new Class[] { Method.class }); } catch (Throwable ignore) { // ignore } return null; } private static Method getIsBridgeMethod() { try { return Method.class.getMethod("isBridge", new Class<?>[] { null }); } catch (NoSuchMethodException e) { return null; } } private static Method getIsSyntheticMethod() { try { return Method.class.getMethod("isSynthetic", new Class<?>[] { null }); } catch (NoSuchMethodException e) { return null; } } private MethodUtil() { } }