jos*_*efx 5 java reflection dynamic-languages
作为开发一个小ScriptEngine的一部分,我反思地调用java方法.脚本引擎的调用为我提供了方法名称和参数数组的对象.要调用该方法,我尝试通过调用Class.getMethod(名称,参数类型)来解决它.
但是,这仅适用于参数的类和Method所期望的类相同的情况.
Object o1 = new Object();
Object out = System.out;
//Works as System.out.println(Object) is defined
Method ms = out.getClass().getMethod("println",o1.getClass());
Object o2 = new Integer(4);
//Does not work as System.out.println(Integer) is not defined
Method mo = out.getClass().getMethod("println",o2.getClass());
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种"简单"的方法来获得正确的方法,如果可能的话,最适合参数类型,或者我必须自己实现.
最贴合的是:
Object o1 = new Integer(1);
Object o2 = new String("");
getMethod(name, o1.getClass())//println(Object)
getMethod(name, o2.getClass())//println(String)
Run Code Online (Sandbox Code Playgroud)
更新:
澄清我需要的东西:脚本引擎是我在空闲时间写的一个小项目,因此我没有必须遵循的严格规则.因此我认为选择从引擎调用的方法与java编译器在编译时仅使用动态类型而不是Object的静态类型选择方法的方式相同.(有或没有自动装箱)
这是我首先希望的Class.getMethod()会解决.但是Class.getMethod()需要与Method声明的参数类型完全相同的类,使用子类将导致没有这样的方法Exception.这可能是有充分理由发生的,但是这个方法对我来说没用,因为我事先并不知道哪种参数类型适合.
另一种方法是调用Class.getMethods()并遍历返回的数组并尝试查找拟合方法.然而,如果我不想采用我遇到的第一个"好"方法,那将会很复杂,所以我希望现有的解决方案至少可以处理:
支持自动装箱也很不错.
如果一个调用无法解析,它可能会抛出一个异常(ma(String,Object),ma(Object,String),args = String,String)
(如果你直到这里,请感谢花时间阅读它: - ))
正如其他人指出的那样,没有标准方法可以执行此操作,因此您将必须实现自己的重载解析算法。
尽可能严格地遵循 javac 的重载解析规则可能是有意义的:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#292575
您可能可以忽略动态的泛型 -类型脚本语言,但您仍然可以从编译器自动生成的桥接方法中受益。
需要注意的一些陷阱:
Class.isAssignableFrom
不知道自动扩展基元转换,因为这些是编译器中实现的语法糖;它们不会出现在 VM 或类层次结构中。例如int.class.isAssignableFrom(short.class)
返回false
。Class.isAssignableFrom
不知道自动装箱。 Integer.class.isAssignableFrom(int.class)
返回false
。Class.isInstance
并Class.cast
以 anObject
作为参数;您不能将原始值传递给它们。它们还返回一个Object
,因此它们不能用于拆箱((int) new Integer(42)
在 Java 源代码中是合法的,但int.class.cast(new Integer(42))
会引发异常。) 归档时间: |
|
查看次数: |
1023 次 |
最近记录: |