Java/Reflection/Interface
Содержание
- 1 Class Reflection: implemented interfaces
- 2 Class Reflection: is it an interface
- 3 Determining If a Class Object Represents a Class or Interface
- 4 Get Super Interfaces
- 5 Listing the Interfaces That a Class Implements
- 6 Listing the Interfaces That an Interface Extends
- 7 Returns true if a class implements Serializable and false otherwise.
- 8 Returns true if type is implementing Map
- 9 Search over classpath retrieving classes that implement a certain interface
- 10 The interfaces for a primitive type is an empty array
- 11 The superclass of interfaces is always null
Class Reflection: implemented interfaces
<source lang="java">
/* 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.io.IOException; import java.io.RandomAccessFile; public class SampleInterface {
public static void main(String[] args) { try { RandomAccessFile r = new RandomAccessFile("myfile", "r"); printInterfaceNames(r); } catch (IOException e) { System.out.println(e); } } static void printInterfaceNames(Object o) { Class c = o.getClass(); Class[] theInterfaces = c.getInterfaces(); for (int i = 0; i < theInterfaces.length; i++) { String interfaceName = theInterfaces[i].getName(); System.out.println(interfaceName); } }
}
</source>
Class Reflection: is it an interface
<source lang="java">
/* 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.util.Observable; import java.util.Observer; public class SampleCheckInterface {
public static void main(String[] args) { Class observer = Observer.class; Class observable = Observable.class; verifyInterface(observer); verifyInterface(observable); } static void verifyInterface(Class c) { String name = c.getName(); if (c.isInterface()) { System.out.println(name + " is an interface."); } else { System.out.println(name + " is a class."); } }
}
</source>
Determining If a Class Object Represents a Class or Interface
<source lang="java">
public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.lang.String.class; boolean isClass = !cls.isInterface(); // true cls = java.lang.Cloneable.class; isClass = !cls.isInterface(); // false }
}
</source>
Get Super Interfaces
<source lang="java">
/*
* The contents of this file are subject to the Sapient Public License * Version 1.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://carbon.sf.net/License.html. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is The Carbon Component Framework. * * The Initial Developer of the Original Code is Sapient Corporation * * Copyright (C) 2003 Sapient Corporation. All Rights Reserved. */
import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; /**
* * * Copyright 2003 Sapient * @since carbon 2.0 * @author Greg Hinkle, March 2003 * @version $Revision: 1.5 $($Author: dvoet $ / $Date: 2003/05/05 21:21:23 $) */
public class ClassUtil {
/** * Retrieves all interfaces implemented by a specified interface * including all recursively extended interfaces and the classes supplied * int the parameter. * @param childInterfaces a set of interfaces * @return Class[] an array of interfaces that includes those specifed * in childInterfaces plus all of those interfaces" super interfaces */ public static Class[] getSuperInterfaces(Class[] childInterfaces) { List allInterfaces = new ArrayList(); for (int i = 0; i < childInterfaces.length; i++) { allInterfaces.add(childInterfaces[i]); allInterfaces.addAll( Arrays.asList( getSuperInterfaces(childInterfaces[i].getInterfaces()))); } return (Class[]) allInterfaces.toArray(new Class[allInterfaces.size()]); } /** * Builds an unordered set of all interface and object classes that * are generalizations of the provided class. * @param classObject the class to find generalization of. * @return a Set of class objects. */ public static Set getGeneralizations(Class classObject) { Set generalizations = new HashSet(); generalizations.add(classObject); Class superClass = classObject.getSuperclass(); if (superClass != null) { generalizations.addAll(getGeneralizations(superClass)); } Class[] superInterfaces = classObject.getInterfaces(); for (int i = 0; i < superInterfaces.length; i++) { Class superInterface = superInterfaces[i]; generalizations.addAll(getGeneralizations(superInterface)); } return generalizations; }
}
</source>
Listing the Interfaces That a Class Implements
<source lang="java">
public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.lang.String.class; Class[] intfs = cls.getInterfaces(); }
}
</source>
Listing the Interfaces That an Interface Extends
<source lang="java">
public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.util.List.class; Class[] intfs = cls.getInterfaces(); // java.util.Collection }
}
</source>
Returns true if a class implements Serializable and false otherwise.
<source lang="java">
import java.io.Serializable; /*
* 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.] * * ------------ * IOUtils.java * ------------ * (C)opyright 2002-2004, by Thomas Morgner and Contributors. * * Original Author: Thomas Morgner; * Contributor(s): David Gilbert (for Object Refinery Limited); * * $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $ * * Changes * ------- * 26-Jan-2003 : Initial version * 23-Feb-2003 : Documentation * 25-Feb-2003 : Fixed Checkstyle issues (DG); * 29-Apr-2003 : Moved to jcommon * 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL; * added support for query strings within these urls (TM); */
public class Main {
/** * Returnstrue
if a class implementsSerializable
* andfalse
otherwise. * * @param c the class. * * @return A boolean. */ public static boolean isSerializable(final Class c) { /** final Class[] interfaces = c.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { if (interfaces[i].equals(Serializable.class)) { return true; } } Class cc = c.getSuperclass(); if (cc != null) { return isSerializable(cc); } */ return (Serializable.class.isAssignableFrom(c)); }
}
</source>
Returns true if type is implementing Map
<source lang="java">
// $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 {
/** * @param type the type to check. * * @return Returnstrue
iftype
is implementingMap
,false
otherwise. */ public static boolean isMap(Type type) { if ( type instanceof Class && isMapClass( ( Class ) type ) ) { return true; } if ( type instanceof ParameterizedType ) { return isMap( ( ( ParameterizedType ) type ).getRawType() ); } if ( type instanceof WildcardType ) { Type[] upperBounds = ( ( WildcardType ) type ).getUpperBounds(); return upperBounds.length != 0 && isMap( upperBounds[0] ); } return false; } /** * Checks whether the specified class parameter is an instance of a collection class. * * @param clazzClass
to check. * * @returntrue
isclazz
is instance of a collection class,false
otherwise. */ private static boolean isMapClass(Class<?> clazz) { List<Class<?>> classes = new ArrayList<Class<?>>(); computeClassHierarchy( clazz, classes ); return classes.contains( Map.class ); } /** * Get all superclasses and interfaces recursively. * * @param clazz The class to start the search with. * @param classes List of classes to which to add all found super classes and interfaces. */ private static void computeClassHierarchy(Class<?> clazz, List<Class<?>> classes) { for ( Class current = clazz; current != null; current = current.getSuperclass() ) { if ( classes.contains( current ) ) { return; } classes.add( current ); for ( Class currentInterface : current.getInterfaces() ) { computeClassHierarchy( currentInterface, classes ); } } }
}
</source>
Search over classpath retrieving classes that implement a certain interface
<source lang="java">
/*
* The contents of this file are subject to the Sapient Public License * Version 1.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://carbon.sf.net/License.html. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is The Carbon Component Framework. * * The Initial Developer of the Original Code is Sapient Corporation * * Copyright (C) 2003 Sapient Corporation. All Rights Reserved. */
import java.io.File; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile;
/**
*This class implements the capability to search over the current classpath * retrieving classes that implement a certain interface.
* * Copyright 2001 Sapient * @since carbon 1.0 * @author Greg Hinkle, June 2001 * @version $Revision: 1.10 $($Author: dvoet $ / $Date: 2003/05/05 21:21:23 $) */
public class ClassFinder {
/** * Tracks the count of classes found that match the * provided criteria. */ protected long foundClasses = 0; /** * The super class criteria */ protected Class superClass = null; /** * The required substring path criteria for this searcher */ protected String requiredPathSubstring = null; /** * The set of classes found matching the provided criteria. */ protected Set classes = new HashSet(2000);
/***
Instantiates the type of MBeanHarvester that will return all classes * in the entire classpath.
*/ public ClassFinder() { } /***
Instantiates the type of MBeanHarvester that will return all classes * that are assignable to the supplied class. This would include all * implementations of it, if it is an interface or it and all subclasses * of it if it"s a class.
* * @param superClass the Class that should be searched for along with * implementations and subclasses */ public ClassFinder(Class superClass) { this.superClass = superClass; } /***
Instantiates the type of MBeanHarvester that will return all classes
* that are assignable to the supplied class and are part of the supplied
* package. This would include all implementations of it, if it is an
* interface or it and all subclasses of it if it"s a class. The
* supplied requiredPathSubstring must be part of the fully
* qualified classname.</p>
*
* @param superClass the Class that should be searched for along with
* implementations and subclasses
* @param requiredPathSubstring the String part that must be found in the
* classes FQN
*/
public ClassFinder(Class superClass, String requiredPathSubstring) {
this.superClass = superClass;
this.requiredPathSubstring = requiredPathSubstring;
}
/**
* <p>Adds a class name to the list of found classes if and only if it meets
* the configured requirements.</p>
*
* @param className the FQN String name of the class to add
*/
protected void addClassName(String className) {
// Only add this class if we"re not checking for a particular
// substring of the FQN or we find that substring
if ((this.requiredPathSubstring == null) ||
(className.indexOf(this.requiredPathSubstring) >= 0)) {
if (this.superClass == null) {
this.classes.add(className);
} else {
try {
// TODO: GH - add a way to search other classpaths and the
// system classpath.
Class theClass =
Class.forName(
className,
false,
this.getClass().getClassLoader());
if (this.superClass.isAssignableFrom(theClass)) {
this.classes.add(className);
}
} catch (ClassNotFoundException cnfe) {
// Used to catch mis-parsed classnames
} catch (Throwable t) {
// Used to catch JVM security and linkage errors
}
}
}
}
/**
* <p>Used to retrieve the results <code>Set
from this harvester"s
* search.
* * @return Set the set of classes that meet this harvester"s requirements */ public Set getClasses() { // 1) tokenize classpath String classpath = System.getProperty("java.class.path"); String pathSeparator = System.getProperty("path.separator"); StringTokenizer st = new StringTokenizer(classpath,pathSeparator); // 2) for each element in the classpath while (st.hasMoreTokens()) { File currentDirectory = new File(st.nextToken()); processFile(currentDirectory.getAbsolutePath(),""); } return this.classes; }
/** * Recursively search through Directories with special checks to recognize * zip and jar files. (Zip and Jar files return true from * <File>.isDirectory()) * @param base the base file path to search * @param current the current recursively searched file path being searched */ private void processFile(String base, String current) { File currentDirectory = new File(base + File.separatorChar + current); // Handle special for archives if (isArchive(currentDirectory.getName())) { try { processZip(new ZipFile(currentDirectory)); } catch (Exception e) { // The directory was not found so the classpath was probably in // error or we don"t have rights to it } return; } else { Set directories = new HashSet(); File[] children = currentDirectory.listFiles(); // if no children, return if (children == null || children.length == 0) { return; } // check for classfiles for (int i = 0; i < children.length; i++) { File child = children[i]; if (child.isDirectory()) { directories.add(children[i]); } else { if (child.getName().endsWith(".class")) { String className = getClassName( current + ((current == "") ? "" : File.separator) + child.getName()); addClassName(className); this.foundClasses++; } } } //call process file on each directory. This is an iterative call!! for (Iterator i = directories.iterator(); i.hasNext(); ) { processFile(base, current + ((current=="")?"":File.separator) + ((File)i.next()).getName()); } } }
/***
Looks at the name of a file to determine if it is an archive
* @param name the name of a file * @return true if a file in the classpath is an archive * such as a Jar or Zip file */ protected boolean isArchive(String name) { if ((name.endsWith(".jar") || (name.endsWith(".zip")))) { return true; } else { return false; } } /***
Returns the Fully Qualified Class name of a class from it"s path * @param fileName the full path to a class * @return the FQN of a class */ protected String getClassName(String fileName) { String newName = fileName.replace(File.separatorChar,"."); // Because zipfiles don"t have platform specific seperators newName = newName.replace("/","."); return newName.substring(0, fileName.length() - 6); } /** * <P>Iterates through the files in a zip looking for files that may be * classes. This is not recursive as zip"s in zip"s are not searched by the * classloader either.
* * @param file The ZipFile to be searched */ protected void processZip(ZipFile file) { Enumeration files = file.entries(); while (files.hasMoreElements()) { Object tfile = files.nextElement(); ZipEntry child = (ZipEntry) tfile; if (child.getName().endsWith(".class")) { addClassName(getClassName(child.getName())); this.foundClasses++; } } }
}
</source>
The interfaces for a primitive type is an empty array
<source lang="java">
public class Main {
public static void main(String[] argv) throws Exception { Class cls = int.class; Class[] intfs = cls.getInterfaces(); // [] }
}
</source>
The superclass of interfaces is always null
<source lang="java">
public class Main {
public static void main(String[] argv) throws Exception { Class cls = java.lang.Cloneable.class; Class sup = cls.getSuperclass(); // null }
}
</source>