⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 methodutils.java

📁 Bean Scripting Framework (BSF)为在java应用中使用脚本语言
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2004,2004 The Apache Software Foundation. *  * 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. */package org.apache.bsf.util;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.Enumeration;import java.util.Vector;/** * This file is a collection of reflection utilities for dealing with * methods and constructors. *  * @author   Sanjiva Weerawarana * @author   Joseph Kesselman */public class MethodUtils {  /** Internal Class for getEntryPoint(). Implements 15.11.2.2 MORE	SPECIFIC rules.	Retains a list of methods (already known to match the	arguments). As each method is added, we check against past entries	to determine which if any is "more specific" -- defined as having	_all_ its arguments (not just a preponderance) be	method-convertable into those of another. If such a relationship	is found, the more-specific method is retained and the	less-specific method is discarded. At the end, if this has yielded	a single winner it is considered the Most Specific Method and	hence the one that should be invoked.  Otherwise, a	NoSuchMethodException is thrown.		PERFORMANCE VERSUS ARCHITECTURE: Arguably, this should "have-a"	Vector. But the code is 6% smaller, and possibly faster, if we	code it as "is-a" Vector. Since it's an inner class, nobody's	likely to abuse the privilage.		Note: "Static" in the case of an inner class means "Does not	reference instance data in the outer class", and is required since	our caller is a static method. */  private static class MoreSpecific  extends Vector  {	/** Submit an entry-point to the list. May be discarded if a past	  entry is more specific, or may cause others to be discarded it	  if is more specific.	  newEntry: Method or Constructor under consideration.	  */	void addItem (Object newEntry)	{	  if(size()==0)		addElement(newEntry);	  else		{		  Class[] newargs=entryGetParameterTypes(newEntry);		  boolean keep=true;		  for (Enumeration e = elements();			   keep & e.hasMoreElements() ;				)			{			  Object oldEntry=e.nextElement();			  // CAVEAT: Implicit references to enclosing class!			  Class[] oldargs=entryGetParameterTypes(oldEntry);			  if(areMethodConvertable(oldargs,newargs))				removeElement(oldEntry); // New more specific; discard old			  else if(areMethodConvertable(newargs,oldargs))				keep=false;     // Old more specific; discard new			  // Else they're tied. Keep both and hope someone beats both.			}		  if(keep)			addElement(newEntry);		}	}	/** Obtain the single Most Specific entry-point. If there is no clear	  winner, or if the list is empty, throw NoSuchMethodException.	  Arguments describe the call we were hoping to resolve. They are	  used to throw a nice verbose exception if something goes wrong.	  */	Object getMostSpecific(Class targetClass,String methodName,						   Class[] argTypes,boolean isStaticReference)		 throws NoSuchMethodException	{	  if(size()==1)		return firstElement();	  if(size()>1)		{		  StringBuffer buf=new StringBuffer();		  Enumeration e=elements();		  buf.append(e.nextElement());		  while(e.hasMoreElements())			buf.append(" and ").append(e.nextElement());		  throw new NoSuchMethodException (callToString(targetClass,														methodName,														argTypes,														isStaticReference)+										   " is ambiguous. It matches "+										   buf.toString());		}	  return null;	}  }  /** Convenience method: Test an entire parameter-list/argument-list pair	for isMethodConvertable(), qv. 	*/  static private boolean areMethodConvertable(Class[] parms,Class[] args)  {	if(parms.length!=args.length)	  return false;		for(int i=0;i<parms.length;++i)	  if(!isMethodConvertable(parms[i],args[i]))		return false;		return true;  }  /** Internal subroutine for getEntryPoint(): Format arguments as a	  string describing the function being searched for. Used in	  verbose exceptions. */  private static String callToString(Class targetClass,String methodName,									Class[] argTypes,boolean isStaticReference)  {	StringBuffer buf = new StringBuffer();	if(isStaticReference)	  buf.append("static ");	buf.append(StringUtils.getClassName(targetClass));	if(methodName!=null)	  buf.append(".").append(methodName);	buf.append("(");	if (argTypes != null && argTypes.length>0) {	  if(false)		{		  // ????? Sanjiva has an ArrayToString method. Using it would		  // save a few bytes, at cost of giving up some reusability.		}	  else		{		  buf.append(StringUtils.getClassName(argTypes[0]));		  for (int i = 1; i < argTypes.length; i++) {			buf.append(",").append(StringUtils.getClassName(argTypes[i]));		  }		}	}	else	  buf.append("[none]");	buf.append(")");	return buf.toString();  }  /** Utility function: obtain common data from either Method or	  Constructor. (In lieu of an EntryPoint interface.) */  static int entryGetModifiers(Object entry)  {	return (entry instanceof Method)	  ? ((Method)entry).getModifiers()	  : ((Constructor)entry).getModifiers();  }  // The common lookup code would be much easier if Method and  // Constructor shared an "EntryPoint" Interface. Unfortunately, even  // though their APIs are almost identical, they don't. These calls  // are a workaround...  at the cost of additional runtime overhead  // and some extra bytecodes.  //  // (A JDK bug report has been submitted requesting that they add the  // Interface; it would be easy, harmless, and useful.)  /** Utility function: obtain common data from either Method or	  Constructor. (In lieu of an EntryPoint interface.) */  static String entryGetName(Object entry)  {	return (entry instanceof Method)	  ? ((Method)entry).getName()	  : ((Constructor)entry).getName();  }  /** Utility function: obtain common data from either Method or	  Constructor. (In lieu of an EntryPoint interface.) */  static Class[] entryGetParameterTypes(Object entry)  {	return (entry instanceof Method)	  ? ((Method)entry).getParameterTypes()	  : ((Constructor)entry).getParameterTypes();  }  /** Utility function: obtain common data from either Method or	  Constructor. (In lieu of an EntryPoint interface.) */  static String entryToString(Object entry)  {	return (entry instanceof Method)	  ? ((Method)entry).toString()	  : ((Constructor)entry).toString();  }  //////////////////////////////////////////////////////////////////////////  /** Class.getConstructor() finds only the entry point (if any)	_exactly_ matching the specified argument types. Our implmentation	can decide between several imperfect matches, using the same	search algorithm as the Java compiler.	Note that all constructors are static by definition, so	isStaticReference is true.	@exception NoSuchMethodException if constructor not found.	*/  static public Constructor getConstructor(Class targetClass, Class[] argTypes)	   throws SecurityException, NoSuchMethodException  {	return (Constructor) getEntryPoint(targetClass,null,argTypes,true);  }  //////////////////////////////////////////////////////////////////////////  /**   * Search for entry point, per  Java Language Spec 1.0   * as amended, verified by comparison against compiler behavior.   *   * @param targetClass Class object for the class to be queried.   * @param methodName  Name of method to invoke, or null for constructor.   *                    Only Public methods will be accepted.   * @param argTypes    Classes of intended arguments.  Note that primitives   *                    must be specified via their TYPE equivalents,    *                    rather than as their wrapper classes -- Integer.TYPE   *                    rather than Integer. "null" may be passed in as an   *                    indication that you intend to invoke the method with   *                    a literal null argument and therefore can accept   *                    any object type in this position.   * @param isStaticReference  If true, and if the target is a Class object,   *                    only static methods will be accepted as valid matches.   *   * @return a Method or Constructor of the appropriate signature   *   * @exception SecurityException     if security violation   * @exception NoSuchMethodException if no such method   */  static private Object getEntryPoint(Class targetClass,									  String methodName,									  Class[] argTypes,									  boolean isStaticReference) 	   throws SecurityException, NoSuchMethodException  {	// 15.11.1: OBTAIN STARTING CLASS FOR SEARCH	Object m=null;		// 15.11.2 DETERMINE ARGUMENT SIGNATURE	// (Passed in as argTypes array.)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -