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

📄 methodutils.java

📁 Bean Scripting Framework (BSF)为在java应用中使用脚本语言
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		// Shortcut: If an exact match exists, return it.	try {	  if(methodName!=null)		{		  m=targetClass.getMethod (methodName, argTypes);		  if(isStaticReference &&			 !Modifier.isStatic(entryGetModifiers(m)) )			{			  throw 				new NoSuchMethodException (callToString (targetClass,														 methodName,														 argTypes,														 isStaticReference)+										   " resolved to instance " + m);			}		  return m;		}	  else		return targetClass.getConstructor (argTypes);		  	} catch (NoSuchMethodException e) {	  // no-args has no alternatives!	  if(argTypes==null || argTypes.length==0)	  {		throw 		  new NoSuchMethodException (callToString (targetClass,												   methodName,												   argTypes,												   isStaticReference)+									 " not found.");	  }	  // Else fall through.	}		// Well, _that_ didn't work. Time to search for the Most Specific	// matching function. NOTE that conflicts are possible!		// 15.11.2.1 ACCESSIBLE: We apparently need to gather from two	// sources to be sure we have both instance and static methods.	Object[] methods;	if(methodName!=null)	  {		methods=targetClass.getMethods();	  }	else	  {		methods=targetClass.getConstructors();	  }	if(0==methods.length)	  {		throw new NoSuchMethodException("No methods!");	  }	MoreSpecific best=new MoreSpecific();	for(int i=0;i<methods.length;++i)	  {		Object mi=methods[i];		if (			// 15.11.2.1 ACCESSIBLE: Method is public.			Modifier.isPublic(entryGetModifiers(mi))			&&			// 15.11.2.1 APPLICABLE: Right method name (or c'tor)			(methodName==null || entryGetName(mi).equals(methodName) )			&&			// 15.11.2.1 APPLICABLE: Parameters match arguments			areMethodConvertable(entryGetParameterTypes(mi),argTypes)			 )		  // 15.11.2.2 MORE SPECIFIC displace less specific.		  best.addItem(mi);	  }	// May throw NoSuchMethodException; we pass in info needed to	// create a useful exception	m=best.getMostSpecific(targetClass,methodName,argTypes,isStaticReference);  	// 15.11.3 APPROPRIATE: Class invocation can call only static	// methods. Note that the defined order of evaluation permits a	// call to be resolved to an inappropriate method and then	// rejected, rather than finding the best of the appropriate	// methods.	//	// Constructors are never static, so we don't test them.	if(m==null)	  {		throw new NoSuchMethodException (callToString(targetClass,													  methodName,													  argTypes,													  isStaticReference)+										 " -- no signature match");	  }	if( methodName!=null &&		isStaticReference &&		!Modifier.isStatic(entryGetModifiers(m)) )	  {		throw new NoSuchMethodException (callToString(targetClass,													  methodName,													  argTypes,													  isStaticReference)+										 " resolved to instance: "+m);	  }	return m;  }  //////////////////////////////////////////////////////////////////////////  /* Class.getMethod() 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.	This version more closely resembles Class.getMethod() -- we always	ask the Class for the method. It differs in testing for	appropriateness before returning the method; if the query is	being made via a static reference, only static methods will be	found and returned. */  static public Method getMethod(Class target,String methodName,								 Class[] argTypes,boolean isStaticReference)	   throws SecurityException, NoSuchMethodException  {	return (Method)getEntryPoint(target,methodName,argTypes,isStaticReference);  }  //////////////////////////////////////////////////////////////////////////  /**   * Class.getMethod() 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.   *   * This version emulates the compiler behavior by allowing lookup to   * be performed against either a class or an instance -- classname.foo()   * must be a static method call, instance.foo() can invoke either static   * or instance methods.   *   * @param target     object on which call is to be made   * @param methodName name of method I'm lookin' for   * @param argTypes   array of argument types of method   *   * @return the desired method   *   * @exception SecurityException     if security violation   * @exception NoSuchMethodException if no such method   */  static public Method getMethod(Object target,String methodName,								 Class[] argTypes)	   throws SecurityException, NoSuchMethodException  {	boolean staticRef=target instanceof Class;	return getMethod( staticRef ? (Class)target : target.getClass(),					  methodName,argTypes,staticRef);  }  /** Determine whether a given type can accept assignments of another	type. Note that class.isAssignable() is _not_ a complete test!	(This method is not needed by getMethod() or getConstructor(), but	is provided as a convenience for other users.)		parm: The type given in the method's signature.	arg: The type we want to pass in.	Legal ASSIGNMENT CONVERSIONS (5.2) are METHOD CONVERSIONS (5.3)	plus implicit narrowing of int to byte, short or char.  */  static private boolean isAssignmentConvertable(Class parm,Class arg)  {	return	  (arg.equals(Integer.TYPE) &&	   (parm.equals(Byte.TYPE) ||		parm.equals(Short.TYPE) ||		parm.equals(Character.TYPE)		 )		) ||	  isMethodConvertable(parm,arg);  }  /** Determine whether a given method parameter type can accept	arguments of another type.	parm: The type given in the method's signature.	arg: The type we want to pass in.	Legal METHOD CONVERSIONS (5.3) are Identity, Widening Primitive	Conversion, or Widening Reference Conversion. NOTE that this is a	subset of the legal ASSIGNMENT CONVERSIONS (5.2) -- in particular,	we can't implicitly narrow int to byte, short or char.	SPECIAL CASE: In order to permit invoking methods with literal	"null" values, setting the arg Class to null will be taken as a	request to match any Class type. POSSIBLE PROBLEM: This may match	a primitive type, which really should not accept a null value... but	I'm not sure how best to distinguish those, short of enumerating them	*/  static private boolean isMethodConvertable(Class parm, Class arg)  {	if (parm.equals(arg))       // If same class, short-circuit now!	  return true;	// Accept any type EXCEPT primitives (which can't have null values).	if (arg == null)	{	  return !parm.isPrimitive();	}	// Arrays are convertable if their elements are convertable	// ????? Does this have to be done before isAssignableFrom, or	// does it successfully handle arrays of primatives?	while(parm.isArray())	  {		if(!arg.isArray())		  return false;         // Unequal array depth		else		  {			parm=parm.getComponentType();			arg=arg.getComponentType();		  }	  }	if(arg.isArray())	  return false;             // Unequal array depth		// Despite its name, the 1.1.6 docs say that this function does	// NOT return true for all legal ASSIGNMENT CONVERSIONS	// (5.2):	//   "Specifically, this method tests whether the type	//   represented by the specified class can be converted	//   to the type represented by this Class object via	//   an identity conversion or via a widening reference	//   conversion."	if(parm.isAssignableFrom(arg))	  return true;	// That leaves us the Widening Primitives case. Four possibilities:	// void (can only convert to void), boolean (can only convert to boolean),	// numeric (which are sequenced) and char (which inserts itself into the	// numerics by promoting to int or larger)	if(parm.equals(Void.TYPE) || parm.equals(Boolean.TYPE) ||	   arg.equals(Void.TYPE) || arg.equals(Boolean.TYPE))	  return false;		Class[] primTypes={ Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE,						Long.TYPE, Float.TYPE, Double.TYPE };	int parmscore,argscore;		for(parmscore=0;parmscore<primTypes.length;++parmscore)	  if (parm.equals(primTypes[parmscore]))		break;	if(parmscore>=primTypes.length)	  return false;             // Off the end		for(argscore=0;argscore<primTypes.length;++argscore)	  if (arg.equals(primTypes[argscore]))		break;	if(argscore>=primTypes.length)	  return false;             // Off the end		// OK if ordered AND NOT char-to-smaller-than-int	return (argscore<parmscore && (argscore!=0 || parmscore>2) );  }}

⌨️ 快捷键说明

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