通过反射动态执行对象的方法的步骤是啥

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过反射动态执行对象的方法的步骤是啥相关的知识,希望对你有一定的参考价值。

这个属于java反射机制范围:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这 种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。主要功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对 象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法,生成动态代理。

动态执行当前类或其父类的方法,支持私有方法。

具体实现方法如下:

 public static void main(String[] args) throws Exception
    Class c = Dynamic.class;//得到对象
    Method[] methods = c.getDeclaredMethods();//得到方法
    for(Method method : methods)
      System.out.print(method.getName());//打印参数名      Class[] parameterTypes = method.getParameterTypes();
      for(int i=0;i<parameterTypes.length;i++)
          String nameString=parameterTypes[i].getName();
          System.out.print("parameterType:"+nameString);//打印方法参数类型      
      
      System.out.print("ReturnType:"+method.getReturnType());
          System.out.println();
      

      Object obj=c.newInstance();//获取到方法对象,假设方法的参数是一个int,String,method名为getAge
      Method sAge = c.getMethod("getAge", new Class[] int.class,String.class);
      //获得参数Object
       Object[] arguments = new Object[]new Integer(23),new String("abc");
      //执行方法
      String s=(String)sAge.invoke(obj , arguments);
     System.out.print(s);
     

     public String  getAge(int age,String name)
           return name+": "+age;
     
参考技术A package test.entity;

public class HelloWorld

private String name;

public String getName()
return name;


public void setName(String name)
this.name = name;


public void hello()
System.out.println("hello world");


------------------------------------------------------------------------------------
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException

Class clazz = Class.forName("test.entity.HelloWorld");
Object obj = clazz.newInstance();
clazz.getMethod("hello").invoke(obj);
本回答被提问者采纳

通过 Java 反射找到 Scala 类型的伴生对象的可靠方法是啥?

【中文标题】通过 Java 反射找到 Scala 类型的伴生对象的可靠方法是啥?【英文标题】:What is a reliable way to find a Scala type's companion object via Java reflection?通过 Java 反射找到 Scala 类型的伴生对象的可靠方法是什么? 【发布时间】:2016-03-17 17:48:38 【问题描述】:

我正在编写 Java(不是 Scala)代码,其中有一个 Java Class 引用,指的是 Scala 类型 T

trait T 

我现在想通过仅使用 Java 反射来发现 Java Class 引用以及与 object T 对应的单例实例,然后调用该伴随对象中的方法。

object T 
  def someMethod : String = "abc";

我对生成的 Scala 代码进行了逆向工程,以编写以下 Java 代码:

Class<?> traitClass = ...;
Class<?> companionClass = Class.forName(traitClass.getName() + "$");
Field module = companionClass.getField("MODULE$");
Object companion = module.get(companionClass);
String abc = (String) companionClass.getMethod("someMethod").invoke(companion);

这看起来不是很健壮——它可能会随着未来的 Scala 编译器而改变。有没有更健壮的方法?我也愿意调用 Scala API(来自 Java)来发现配套实例。

【问题讨论】:

嗯。那么您是否尝试过使用 scala.meta ?这里:github.com/scalameta/scalameta. @SomBhattacharyya:我不想为此使用库。特别不是 Scala 库,因为我在 Java 中实现它 哦,好的,我明白了。老实说 Scala 改变他们的二进制版本的方式,我认为很难写出“更好”或“可持续”的东西。 @SomBhattacharyya:我害怕那个。但也很好奇其他人是否遇到过这个问题,并以某种方式解决了它 是的,我也很想知道。很好的问题。 【参考方案1】:

您编写的代码适用于***(包拥有的)同伴。它也适用于嵌套类/特征对象对的基本情况,但有些情况下简单的name + $ 方案不成立。这是和示例:

class C 
  class D
  object D
  def foo() 
    class K
    object K
  

这会生成类文件CC$DC$D$C$K$2C$K$3$

虽然编码可能在未来的任何时间发生变化,但它在很长一段时间内都没有变化,也没有计划改变。我刚试了2.5.0,除了嵌套在方法中的类,类名都是一样的。

如果您可以控制 Scala 类,最简单的方法是将方法 def companion = T 添加到 trait T

另一种选择是使用 Scala 反射 API:

scala> import scala.reflect.runtime.universe => ru
scala> val m = ru.runtimeMirror(getClass.getClassLoader)

scala> val d = classOf[C$D]
d: Class[C$D] = class C$D

scala> m.runtimeClass(m.classSymbol(d).companionSymbol.asModule.moduleClass.asClass)
res16: Class[_] = class C$D$

但这在嵌套在方法中的类上也不能按预期工作:

scala> val k = classOf[C$K$2]
k: Class[C$K$2] = class C$K$2

scala> m.classSymbol(k).companionSymbol
res2: reflect.runtime.universe.Symbol = <none>

请注意,在 SO 上搜索“scala 反射伴侣”也会产生几个结果(并显示一些问题)。

【讨论】:

优秀。如果这在很长一段时间内都没有改变,我怀疑我的方法对于我的用例来说是“足够好”。关于 “如果您可以控制 Scala 类,最简单的方法是添加方法 def partner = T 到 trait T。” - 不幸的是,我没有 instance i> 的特征 T,只有它的 Class 引用。所以,我不能真正调用任何这样的方法(除非我可以强制 Scala 在 trait 上生成静态方法)-“请注意,在 SO 上搜索“scala 反射伴侣”也会产生几个结果” i> 是的,但通常是从 Scala 中执行此操作,而不是从 Java :)

以上是关于通过反射动态执行对象的方法的步骤是啥的主要内容,如果未能解决你的问题,请参考以下文章

通过 Java 反射找到 Scala 类型的伴生对象的可靠方法是啥?

Android 让反射变的简单

通过反射动态创建对象方法

JAVA中反射是啥

Java反射及动态代理

反射常见方法