/** * 根据给定的一个方法,判断其是 Getter 还是 Setter * * <p>对于回调会接受三个参数 * * <pre> * callback(虚字段名, getter, setter) * </pre> * * 回调都会给一个参数,表示这个方法对应的虚拟字段名。所谓"虚拟字段",就比如 * * <ul> * <li>如果是 setAbc : 那么就是 "abc" * <li>如果是 getAbc : 那么就是 "abc" * <li>如果是 isAbc : 那么就是 "abc" * </ul> * * 而 getter 或者 setter 参数如果为 null,则表示本函数未发现对应的 getter|setter * * @param method 方法对象 * @param callback 回调, 如果为 null,则无视 * @param whenError 如果本方法即不是 Getter 也不是 Setter 的回调, 如果为 null,则无视 */ public static void evalGetterSetter( Method method, Callback3<String, Method, Method> callback, Callback<Method> whenError) { String name = method.getName(); Method getter = null; Method setter = null; // 是 getter if (name.startsWith("get") && method.getParameterTypes().length == 0) { name = Strings.lowerFirst(name.substring(4)); getter = method; // 寻找 setter try { setter = method .getDeclaringClass() .getMethod("set" + Strings.capitalize(name), method.getReturnType()); } catch (Exception e) { } } // 布尔的 getter else if (name.startsWith("is") && Mirror.me(method.getReturnType()).isBoolean() && method.getParameterTypes().length == 0) { name = Strings.lowerFirst(name.substring(3)); getter = method; // 寻找 setter try { setter = method .getDeclaringClass() .getMethod("set" + Strings.capitalize(name), method.getReturnType()); } catch (Exception e) { } } // 是 setter else if (name.startsWith("set") && method.getParameterTypes().length == 1) { name = Strings.lowerFirst(name.substring(4)); setter = method; // 寻找 getter try { getter = method.getDeclaringClass().getMethod("get" + Strings.capitalize(name)); } catch (Exception e) { } } // 虾米都不是,错! else { if (null != whenError) whenError.invoke(method); return; } // 最后调用回调 if (null != callback) callback.invoke(name, getter, setter); }
/** * 根据一个字段名和字段类型获取 Setter * * @param fieldName 字段名 * @param paramType 字段类型 * @return 方法 * @throws NoSuchMethodException 没找到 Setter */ public Method getSetter(String fieldName, Class<?> paramType) throws NoSuchMethodException { try { String setterName = "set" + Strings.capitalize(fieldName); try { return klass.getMethod(setterName, paramType); } catch (Throwable e) { try { return klass.getMethod(fieldName, paramType); } catch (Throwable e1) { Mirror<?> type = Mirror.me(paramType); for (Method method : klass.getMethods()) { if (method.getParameterTypes().length == 1) if (method.getName().equals(setterName) || method.getName().equals(fieldName)) { if (null == paramType || type.canCastToDirectly(method.getParameterTypes()[0])) return method; } } // 还是没有? 会不会是包装类型啊? if (!paramType.isPrimitive()) { Class<?> p = unWrapper(); if (null != p) return getSetter(fieldName, p); } throw new RuntimeException(); } } } catch (Throwable e) { throw Lang.makeThrow( NoSuchMethodException.class, "Fail to find setter for [%s]->[%s(%s)]", klass.getName(), fieldName, paramType.getName()); } }
/** * 根据一个字段名,获取一组有可能成为 Setter 函数 * * @param fieldName * @return 函数数组 */ public Method[] findSetters(String fieldName) { String mName = "set" + Strings.capitalize(fieldName); List<Method> ms = new ArrayList<Method>(); for (Method m : this.klass.getMethods()) { if (!Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 1 && m.getName().equals(mName)) ms.add(m); } return ms.toArray(new Method[ms.size()]); }
/** * 根据名称获取一个 Getter。 * * <p>比如,你想获取 abc 的 getter ,那么优先查找 getAbc(),如果没有则查找isAbc(),最后才是查找 abc()。 * * @param fieldName * @return 方法 * @throws NoSuchMethodException 没有找到 Getter */ public Method getGetter(String fieldName) throws NoSuchMethodException { String fn = Strings.capitalize(fieldName); String _get = "get" + fn; String _is = "is" + fn; for (Method method : klass.getMethods()) { if (method.getParameterTypes().length != 0) continue; if (_get.equals(method.getName())) return method; if (_is.equals(method.getName())) { if (!Mirror.me(method.getReturnType()).isBoolean()) throw new NoSuchMethodException(); return method; } if (fieldName.equals(method.getName())) return method; } throw Lang.makeThrow( NoSuchMethodException.class, "Fail to find getter for [%s]->[%s]", klass.getName(), fieldName); }
private void addSetProperty(Object bean, Class<?>[] type, String name, Object... property) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (name == null) { name = type[0].getSimpleName(); } int dot; if ((dot = name.indexOf('.')) > -1) { _logger.fine("looking at a composite property " + name); do { bean = Beans.invoke(bean, "get" + name.substring(0, dot)); name = Strings.capitalize( name.substring(dot + 1)); // lower case letters may be found after '.' } while ((dot = name.indexOf('.')) > -1); } // attempt property injection using setXXX(), addXXX(), set(), or add(), in that order try { _logger.fine( S.fine(_logger) ? "trying set" + name + "() on " + bean.getClass() + ": " + property.length + args(property) : null); Beans.invoke(bean, "set" + name, property); _logger.fine("... successful"); } catch (NoSuchMethodException x) { try { _logger.fine( S.fine(_logger) ? "trying add" + name + "() on " + bean.getClass() + ": " + property.length + args(property) : null); Beans.invoke(bean, "add" + name, property); _logger.fine("... successful"); } catch (NoSuchMethodException x1) { try { _logger.fine( S.fine(_logger) ? "trying set() on " + bean.getClass() + ": " + property.length + args(property) : null); Beans.invoke(bean, "set", property); _logger.fine("... successful"); } catch (NoSuchMethodException x2) { _logger.fine( S.fine(_logger) ? "trying add() on " + bean.getClass() + ": " + property.length + args(property) : null); Beans.invoke(bean, "add", property); _logger.fine("... successful"); } } } }