Java/Reflection/Inheritance
Содержание
Class comparator: compare and sort classes and their superclasses.
<source lang="java">
/*
* JCommon : a free general purpose class library for the Java(tm) platform * * * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jcommon/index.html * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. * * [Java is a trademark or registered trademark of Sun Microsystems, Inc. * in the United States and other countries.] * * -------------------- * ClassComparator.java * -------------------- * (C)opyright 2003-2005, by Thomas Morgner and Contributors. * * Original Author: Thomas Morgner (taquera@sherito.org); * Contributor(s): David Gilbert (for Object Refinery Limited); * * $Id: ClassComparator.java,v 1.3 2005/10/18 13:24:19 mungady Exp $ * * Changes * ------- * 02-May-2003 : Initial version * */
import java.io.Serializable; import java.util.ruparator; /**
* The class comparator can be used to compare and sort classes and their * superclasses. The comparator is not able to compare classes which have no * relation... * * @author Thomas Morgner */
public class ClassComparator implements Comparator, Serializable {
/** For serialization. */ private static final long serialVersionUID = -5225335361837391120L; /** * Defaultconstructor. */ public ClassComparator() { super(); } /** * Compares its two arguments for order. Returns a negative integer, zero, or * a positive integer as the first argument is less than, equal to, or greater * than the second.*
* <P> * Note: throws ClassCastException if the arguments" types prevent them from * being compared by this Comparator. And IllegalArgumentException if the * classes share no relation. * * The implementor must ensure that sgn(compare(x, y)) == * -sgn(compare(y, x)) * for all x and y. (This implies that * compare(x, y) must throw an exception if and only if * compare(y, x) throws an exception.) * <p> * * The implementor must also ensure that the relation is transitive: * ((compare(x, y)>0) && (compare(y, z)>0)) implies * compare(x, z)>0. * <p> * * Finally, the implementer must ensure that compare(x, y)==0 * implies that sgn(compare(x, z))==sgn(compare(y, z)) for all * z. * <p> * * It is generally the case, but not strictly required that * (compare(x, y)==0) == (x.equals(y)). Generally speaking, any * comparator that violates this condition should clearly indicate this fact. * The recommended language is "Note: this comparator imposes orderings that * are inconsistent with equals." * * @param o1 * the first object to be compared. * @param o2 * the second object to be compared. * @return a negative integer, zero, or a positive integer as the first * argument is less than, equal to, or greater than the second. */ public int compare(final Object o1, final Object o2) { final Class c1 = (Class) o1; final Class c2 = (Class) o2; if (c1.equals(o2)) { return 0; } if (c1.isAssignableFrom(c2)) { return -1; } else { if (!c2.isAssignableFrom(c2)) { throw new IllegalArgumentException("The classes share no relation"); } return 1; } } /** * Checks, whether the given classes are comparable. This method will return * true, if one of the classes is assignable from the other class. * * @param c1 * the first class to compare * @param c2 * the second class to compare * @return true, if the classes share a direct relation, false otherwise. */ public boolean isComparable(final Class c1, final Class c2) { return (c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1)); } } </source>
Find Inherited Field
<source lang="java">
// //$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $ //Copyright 2006 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. // import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; public class IntrospectionUtil {
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); } }
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); }
}
</source>
Find Inherited Method
<source lang="java">
// //$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $ //Copyright 2006 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. // import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; public class IntrospectionUtil {
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); } }
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); }
}
</source>
Is Inheritable
<source lang="java">
// //$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $ //Copyright 2006 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at //http://www.apache.org/licenses/LICENSE-2.0 //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. //
import java.lang.reflect.Member; import java.lang.reflect.Modifier; public class Utils {
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; }
}
</source>
Return a List of super-classes for the given class.
<source lang="java">
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; 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 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; }
}
</source>