Java/Reflection/Interface

Материал из Java эксперт
Перейти к: навигация, поиск

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 {

 /**
  * Returns true if a class implements Serializable
  * and false 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 Returns true if type is implementing Map, 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 clazz Class to check.
  *
  * @return true is clazz 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>