Java/Reflection/Class Method Field Name

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

Create a new instance given a class name

   <source lang="java">

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.net.MalformedURLException; import java.net.URL; /**

* A collection of class management utility methods.
*
* @version $Id: ClassUtils.java 587751 2007-10-24 02:41:36Z vgritsenko $
*/

public class ClassUtils {

   /**
    * Create a new instance given a class name
    *
    * @param className A class name
    * @return A new instance
    * @exception Exception If an instantiation error occurs
    */
   public static Object newInstance(String className) throws Exception {
       return loadClass(className).newInstance();
   }
   /**
    * Load a class given its name.
    * BL: We wan"t to use a known ClassLoader--hopefully the heirarchy
    *     is set correctly.
    *
    * @param className A class name
    * @return The class pointed to by className
    * @exception ClassNotFoundException If a loading error occurs
    */
   public static Class loadClass(String className) throws ClassNotFoundException {
       return getClassLoader().loadClass(className);
   }
   /**
    * Return a resource URL.
    * BL: if this is command line operation, the classloading issues
    *     are more sane.  During servlet execution, we explicitly set
    *     the ClassLoader.
    *
    * @return The context classloader.
    * @exception MalformedURLException If a loading error occurs
    */
   public static URL getResource(String resource) throws MalformedURLException {
       return getClassLoader().getResource(resource);
   }
   /**
    * Return the context classloader.
    * BL: if this is command line operation, the classloading issues
    *     are more sane.  During servlet execution, we explicitly set
    *     the ClassLoader.
    *
    * @return The context classloader.
    */
   public static ClassLoader getClassLoader() {
       return Thread.currentThread().getContextClassLoader();
   }

}

 </source>
   
  
 
  



Create a unique hash for Constructor and method

   <source lang="java">

/*

* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; /**

* Create a unique hash for
* 
* @author 
* @version $Revision: 2787 $
*/

@SuppressWarnings("unchecked") public class MethodHashing {

 // Constants -----------------------------------------------------
 // Static --------------------------------------------------------
 static Map hashMap = new WeakHashMap();
 public static Method findMethodByHash(Class clazz, long hash) throws Exception {
   Method[] methods = clazz.getDeclaredMethods();
   for (int i = 0; i < methods.length; i++) {
     if (methodHash(methods[i]) == hash)
       return methods[i];
   }
   if (clazz.getSuperclass() != null) {
     return findMethodByHash(clazz.getSuperclass(), hash);
   }
   return null;
 }
 public static Constructor findConstructorByHash(Class clazz, long hash) throws Exception {
   Constructor[] cons = clazz.getDeclaredConstructors();
   for (int i = 0; i < cons.length; i++) {
     if (constructorHash(cons[i]) == hash)
       return cons[i];
   }
   if (clazz.getSuperclass() != null) {
     return findConstructorByHash(clazz.getSuperclass(), hash);
   }
   return null;
 }
 public static long methodHash(Method method) throws Exception {
   Class[] parameterTypes = method.getParameterTypes();
   String methodDesc = method.getName() + "(";
   for (int j = 0; j < parameterTypes.length; j++) {
     methodDesc += getTypeString(parameterTypes[j]);
   }
   methodDesc += ")" + getTypeString(method.getReturnType());
   long hash = 0;
   ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(512);
   MessageDigest messagedigest = MessageDigest.getInstance("SHA");
   DataOutputStream dataoutputstream = new DataOutputStream(new DigestOutputStream(
       bytearrayoutputstream, messagedigest));
   dataoutputstream.writeUTF(methodDesc);
   dataoutputstream.flush();
   byte abyte0[] = messagedigest.digest();
   for (int j = 0; j < Math.min(8, abyte0.length); j++)
     hash += (long) (abyte0[j] & 0xff) << j * 8;
   return hash;
 }
 public static long constructorHash(Constructor method) throws Exception {
   Class[] parameterTypes = method.getParameterTypes();
   String methodDesc = method.getName() + "(";
   for (int j = 0; j < parameterTypes.length; j++) {
     methodDesc += getTypeString(parameterTypes[j]);
   }
   methodDesc += ")";
   long hash = 0;
   ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(512);
   MessageDigest messagedigest = MessageDigest.getInstance("SHA");
   DataOutputStream dataoutputstream = new DataOutputStream(new DigestOutputStream(
       bytearrayoutputstream, messagedigest));
   dataoutputstream.writeUTF(methodDesc);
   dataoutputstream.flush();
   byte abyte0[] = messagedigest.digest();
   for (int j = 0; j < Math.min(8, abyte0.length); j++)
     hash += (long) (abyte0[j] & 0xff) << j * 8;
   return hash;
 }
 /**
  * Calculate method hashes. This algo is taken from RMI.
  * 
  * @param intf
  * @return the map
  */
 public static Map getInterfaceHashes(Class intf) {
   // Create method hashes
   Method[] methods = intf.getDeclaredMethods();
   HashMap map = new HashMap();
   for (int i = 0; i < methods.length; i++) {
     Method method = methods[i];
     try {
       long hash = methodHash(method);
       map.put(method.toString(), new Long(hash));
     } catch (Exception e) {
     }
   }
   return map;
 }
 static String getTypeString(Class cl) {
   if (cl == Byte.TYPE) {
     return "B";
   } else if (cl == Character.TYPE) {
     return "C";
   } else if (cl == Double.TYPE) {
     return "D";
   } else if (cl == Float.TYPE) {
     return "F";
   } else if (cl == Integer.TYPE) {
     return "I";
   } else if (cl == Long.TYPE) {
     return "J";
   } else if (cl == Short.TYPE) {
     return "S";
   } else if (cl == Boolean.TYPE) {
     return "Z";
   } else if (cl == Void.TYPE) {
     return "V";
   } else if (cl.isArray()) {
     return "[" + getTypeString(cl.getComponentType());
   } else {
     return "L" + cl.getName().replace(".", "/") + ";";
   }
 }
 /*
  * The use of hashCode is not enough to differenciate methods we override the
  * hashCode
  * 
  * The hashes are cached in a static for efficiency RO: WeakHashMap needed to
  * support undeploy
  */
 public static long calculateHash(Method method) {
   Map methodHashes = (Map) hashMap.get(method.getDeclaringClass());
   if (methodHashes == null) {
     methodHashes = getInterfaceHashes(method.getDeclaringClass());
     // Copy and add
     WeakHashMap newHashMap = new WeakHashMap();
     newHashMap.putAll(hashMap);
     newHashMap.put(method.getDeclaringClass(), methodHashes);
     hashMap = newHashMap;
   }
   return ((Long) methodHashes.get(method.toString())).longValue();
 }

}

 </source>
   
  
 
  



Format a string buffer containing the Class, Interfaces, CodeSource, and ClassLoader information for the given object clazz.

   <source lang="java">

import java.lang.reflect.Method; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; import java.util.HashSet; import java.util.List; import java.util.Set; /*

* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

public class Main {

 /**
  * Format a string buffer containing the Class, Interfaces, CodeSource, and
  * ClassLoader information for the given object clazz.
  * 
  * @param clazz
  *          the Class
  * @param results -
  *          the buffer to write the info to
  */
 public static void displayClassInfo(Class clazz, StringBuffer results) {
   // Print out some codebase info for the clazz
   ClassLoader cl = clazz.getClassLoader();
   results.append("\n");
   results.append(clazz.getName());
   results.append("(");
   results.append(Integer.toHexString(clazz.hashCode()));
   results.append(").ClassLoader=");
   results.append(cl);
   ClassLoader parent = cl;
   while (parent != null) {
     results.append("\n..");
     results.append(parent);
     URL[] urls = getClassLoaderURLs(parent);
     int length = urls != null ? urls.length : 0;
     for (int u = 0; u < length; u++) {
       results.append("\n....");
       results.append(urls[u]);
     }
     if (parent != null)
       parent = parent.getParent();
   }
   CodeSource clazzCS = clazz.getProtectionDomain().getCodeSource();
   if (clazzCS != null) {
     results.append("\n++++CodeSource: ");
     results.append(clazzCS);
   } else
     results.append("\n++++Null CodeSource");
   results.append("\nImplemented Interfaces:");
   Class[] ifaces = clazz.getInterfaces();
   for (int i = 0; i < ifaces.length; i++) {
     Class iface = ifaces[i];
     results.append("\n++");
     results.append(iface);
     results.append("(");
     results.append(Integer.toHexString(iface.hashCode()));
     results.append(")");
     ClassLoader loader = ifaces[i].getClassLoader();
     results.append("\n++++ClassLoader: ");
     results.append(loader);
     ProtectionDomain pd = ifaces[i].getProtectionDomain();
     CodeSource cs = pd.getCodeSource();
     if (cs != null) {
       results.append("\n++++CodeSource: ");
       results.append(cs);
     } else
       results.append("\n++++Null CodeSource");
   }
 }
 /**
  * Use reflection to access a URL[] getURLs or URL[] getClasspath method so
  * that non-URLClassLoader class loaders, or class loaders that override
  * getURLs to return null or empty, can provide the true classpath info.
  * 
  * @param cl
  * @return the urls
  */
 public static URL[] getClassLoaderURLs(ClassLoader cl) {
   URL[] urls = {};
   try {
     Class returnType = urls.getClass();
     Class[] parameterTypes = {};
     Class clClass = cl.getClass();
     Method getURLs = clClass.getMethod("getURLs", parameterTypes);
     if (returnType.isAssignableFrom(getURLs.getReturnType())) {
       Object[] args = {};
       urls = (URL[]) getURLs.invoke(cl, args);
     }
     if (urls == null || urls.length == 0) {
       Method getCp = clClass.getMethod("getClasspath", parameterTypes);
       if (returnType.isAssignableFrom(getCp.getReturnType())) {
         Object[] args = {};
         urls = (URL[]) getCp.invoke(cl, args);
       }
     }
   } catch (Exception ignore) {
   }
   return urls;
 }

}

 </source>
   
  
 
  



Get non Package Qualified Name

   <source lang="java">


public class Utils {

 public static String nonPackageQualifiedName( final Class<?> clazz ) {
     String name = clazz.getName();
     return name.substring(name.lastIndexOf(".") + 1);
 }

}

 </source>
   
  
 
  



Get the short name of the specified class by striping off the package name.

   <source lang="java">

import java.lang.reflect.Method; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; import java.util.HashSet; import java.util.List; import java.util.Set; /*

* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

public class Main {

 /** The string used to separator packages */
 public static final String PACKAGE_SEPARATOR = ".";
 /**
  * Get the short name of the specified class by striping off the package name.
  * 
  * @param classname
  *          Class name.
  * @return Short class name.
  */
 public static String stripPackageName(final String classname) {
   int idx = classname.lastIndexOf(PACKAGE_SEPARATOR);
   if (idx != -1)
     return classname.substring(idx + 1, classname.length());
   return classname;
 }

}

 </source>
   
  
 
  



Load a class given its name.

   <source lang="java">

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.net.MalformedURLException; import java.net.URL; /**

* A collection of class management utility methods.
*
* @version $Id: ClassUtils.java 587751 2007-10-24 02:41:36Z vgritsenko $
*/

public class ClassUtils {

   /**
    * Load a class given its name.
    * BL: We wan"t to use a known ClassLoader--hopefully the heirarchy
    *     is set correctly.
    *
    * @param className A class name
    * @return The class pointed to by className
    * @exception ClassNotFoundException If a loading error occurs
    */
   public static Class loadClass(String className) throws ClassNotFoundException {
       return getClassLoader().loadClass(className);
   }
   /**
    * Return a resource URL.
    * BL: if this is command line operation, the classloading issues
    *     are more sane.  During servlet execution, we explicitly set
    *     the ClassLoader.
    *
    * @return The context classloader.
    * @exception MalformedURLException If a loading error occurs
    */
   public static URL getResource(String resource) throws MalformedURLException {
       return getClassLoader().getResource(resource);
   }
   /**
    * Return the context classloader.
    * BL: if this is command line operation, the classloading issues
    *     are more sane.  During servlet execution, we explicitly set
    *     the ClassLoader.
    *
    * @return The context classloader.
    */
   public static ClassLoader getClassLoader() {
       return Thread.currentThread().getContextClassLoader();
   }

}

 </source>
   
  
 
  



Returns an instance of the given class name, by calling the default constructor.

   <source lang="java">

/*

* $Id: ClassUtil.java 709153 2008-10-30 12:54:10Z apetrelli $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.
*/

/**

* Utilities to work with dynamic class loading and instantiation.
*
* @version $Rev: 709153 $ $Date: 2008-10-30 13:54:10 +0100 (Thu, 30 Oct 2008) $
* @since 2.0.7
*/

public class Main {

 /**
  * Returns an instance of the given class name, by calling the default
  * constructor.
  *
  * @param className The class name to load and to instantiate.
  * @param returnNull If true, if the class is not found it
  * returns true, otherwise it throws a
  * TilesException.
  * @return The new instance of the class name.
  * @throws CannotInstantiateObjectException If something goes wrong during instantiation.
  * @since 2.0.7
  */
 public static Object instantiate(String className, boolean returnNull) {
     ClassLoader original = Thread.currentThread().getContextClassLoader();
     if (original == null) {
         Thread.currentThread().setContextClassLoader(Main.class.getClassLoader());
     }
     try {
         Class<?> namedClass = Class.forName(className);
         return namedClass.newInstance();
     } catch (ClassNotFoundException e) {
         if (returnNull) {
             return null;
         }
         throw new RuntimeException(
                 "Unable to resolve factory class: "" + className + """, e);
     } catch (IllegalAccessException e) {
         throw new RuntimeException(
                 "Unable to access factory class: "" + className + """, e);
     } catch (InstantiationException e) {
         throw new RuntimeException(
                 "Unable to instantiate factory class: ""
                         + className
                         + "". Make sure that this class has a default constructor",
                 e);
     } finally {
         // If the original context classloader of the current thread was
         // null, it must be reset.
         if (original == null) {
             Thread.currentThread().setContextClassLoader(null);
         }
     }
 }

}

 </source>
   
  
 
  



Returns the name of a class without the package name

   <source lang="java">

public class Utils {

 /**
  * Returns the name of a class without the package name.  For example: if
  * input = "java.lang.Object" , then output = "Object".
  * @param fully qualified classname
  * @return the unqualified classname 
  */
 public static String getShortClassName(final String className) {
     if (className != null) {
         final int index = className.lastIndexOf(".");
         return className.substring(index + 1);
     }
     return null;
 }

}

 </source>
   
  
 
  



Returns the package portion of the specified class

   <source lang="java">

public class Utils {

 /**
  * Returns the package portion of the specified class
  * @param className the name of the class from which to extract the package
  * @return package portion of the specified class
  */
 public static String getPackageName(final String className) {
     if (className != null) {
         final int index = className.lastIndexOf(".");
         return ((index != -1) ? className.substring(0, index) : ""); // NOI18N
     }
     return null;
 }

}

 </source>