Java/Reflection/Class Method Field Name
Содержание
- 1 Create a new instance given a class name
- 2 Create a unique hash for Constructor and method
- 3 Format a string buffer containing the Class, Interfaces, CodeSource, and ClassLoader information for the given object clazz.
- 4 Get non Package Qualified Name
- 5 Get the short name of the specified class by striping off the package name.
- 6 Load a class given its name.
- 7 Returns an instance of the given class name, by calling the default constructor.
- 8 Returns the name of a class without the package name
- 9 Returns the package portion of the specified class
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 Iftrue
, if the class is not found it * returnstrue
, 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>