【问题标题】:Generate java class and call its method dynamically生成java类并动态调用其方法
【发布时间】:2010-03-24 21:30:37
【问题描述】:
package reflection;

import java.io.*;

import java.lang.reflect.*;

class class0
{
  public void writeout0()
  {
    System.out.println("class0");
  }
}

class class1
{
  public void writeout1()
  { 
    System.out.println("class1");
  }
}

class class2
{
  public void writeout2()
  {
    System.out.println("class2");
  }
}

 class class3

{

  public void run()

  {

    try

    {    

        BufferedReader reader= new BufferedReader(new InputStreamReader

(System.in)); 

          String line=reader.readLine(); 

          Class cls=Class.forName(line);
                 //define method here



    }

    catch(Exception ee)

    {

   System.out.println("here "+ee);

    }


  }
  public void writeout3()
  {
      System.out.println("class3");
  }
}

class class4
{
  public void writeout4()
  {
    System.out.println("class4");
  }
}

class class5
{
  public void writeout5()
  {
    System.out.println("class5");
  }
}

class class6
{
  public void writeout6()
  {
    System.out.println("class6");
  }
}

class class7
{
  public void writeout7()
  {
    System.out.println("class7");
  }
}

class class8
{
  public void writeout8()
  {
    System.out.println("class8");
  }
}

class class9
{
  public void writeout9()
  {
    System.out.println("class9");
  }
}



class testclass {

    public static void main(String[] args) {

       System.out.println("Write class name : ");

        class3 example=new class3();

        example.run();
    }

}

问题是; 第三个类将从控制台读取类的名称作为字符串。读取类名后,会自动动态生成该类并调用其writeout方法。如果该类没有从输入中读取,则不会被初始化。

但我不能再继续了; 3.class 我需要更多的东西,我该怎么办?

【问题讨论】:

  • 我很高兴地意识到他的课程只有 10 个课程。
  • 这是一个 Java 反射教程:java.sun.com/docs/books/tutorial/reflect 你可能会发现它很有用。
  • “生成该类”是什么意思?实例化该类的对象?
  • @Jacob:您不应该将run 方法放在类3 上,可以在测试类的main 方法中使用相同的代码。 (Java 类名中的 BTW 按照约定以大写开头)

标签: java reflection


【解决方案1】:

到目前为止,您已经有了一个 Class 对象。您需要实例化该类以拥有一个对象来调用方法。获得所需的实例后,您可以通过调用 Class 对象上的 getMethod(String name, Class... parameterTypes) 找到所需的方法。如果所有类对于“writeout()”方法具有相同的方法名称,这将很有帮助,否则您必须弄清楚该方法在类内部的名称。这是调用“writeout()”时缺少的代码:

  Method m = cls.getMethod("writeout", null);
  Object writerInstance = cls.newInstance();

  m.invoke(writerInstance, null);

使用示例中的类和方法命名方案,您可以通过解析类名并提取数字来找出方法名。不过,如果所有类都共享方法名,那就容易多了。

【讨论】:

    【解决方案2】:

    您需要通过类加载器动态加载类。一个简单的方法是使用:

    Class.forName(yourClassName);
    

    获取类对象,然后newInstance() 创建该类的新实例。该特定方法仅适用于具有默认构造函数的类。有关更多选项,请参阅Class javadoc。调用构造函数。

    【讨论】:

    • 我认为他想先使用 getMethods 检查方法,然后检查是否写入,然后实例化对象..但我不明白这个问题
    • 我同意它可以解释
    【解决方案3】:

    为了动态生成 Java 类文件,有一个名为 Byte Code Engeneering Library (BCEL) 的库,它将生成的字节码指令包装在类文件周围并将其加载到运行时中。

    不过,您必须了解一些有关 Java 虚拟机的知识。

    我建议创建一个包含“writeOut”方法的接口。生成的类需要实现这个接口。加载类时,调用该方法不需要(太多)反射。您需要的唯一反射是创建生成的类的实例。

    【讨论】:

      【解决方案4】:

      继续类似:

      //define method here
      
      Method writeout = null;
      for( Method m : cls.getDeclaredMethods() ) {
         if( m.getName().startsWith("writeout")) {
             writeout = m;
             break;
         }
      }
      Object o = cls.newInstance();
      writeout.invoke( o );
      

      基本上,一旦找到了类,就必须找到要调用的方法并创建该类的实例以最终在该新实例上调用该方法。

      要了解更多(更好)所有这些概念,您应该阅读有关该主题的 java 教程:The Reflection API

      顺便说一句,您不是在这里生成一个类,而是动态地实例化它。

      【讨论】:

        【解决方案5】:

        供您参考的简单示例:

        Class<?> cls_obj = Class.forName("MyClass.java");
        Method method = cls_obj.getMethod("show");
        Object obj = cls_obj.newInstance();
        method.invoke(obj);
        

        【讨论】:

          猜你喜欢
          • 2013-03-08
          • 2023-03-16
          • 2012-01-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-17
          • 2012-07-20
          • 2021-10-22
          相关资源
          最近更新 更多