【问题标题】:How do I pass a class as a parameter in Java?如何在 Java 中将类作为参数传递?
【发布时间】:2011-06-19 20:49:56
【问题描述】:

有没有办法在 Java 中将类作为参数传递并从该类中触发一些方法?

void main()
{
    callClass(that.class)
}

void callClass(???? classObject)
{
    classObject.somefunction
    // or 
    new classObject()
    //something like that ?
}

我使用的是 Google Web Toolkit,它不支持反射。

【问题讨论】:

    标签: java class gwt parameters


    【解决方案1】:
    public void foo(Class c){
            try {
                Object ob = c.newInstance();
            } catch (InstantiationException ex) {
                Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    

    如何使用反射调用方法

     import java.lang.reflect.*;
    
    
       public class method2 {
          public int add(int a, int b)
          {
             return a + b;
          }
    
          public static void main(String args[])
          {
             try {
               Class cls = Class.forName("method2");
               Class partypes[] = new Class[2];
                partypes[0] = Integer.TYPE;
                partypes[1] = Integer.TYPE;
                Method meth = cls.getMethod(
                  "add", partypes);
                method2 methobj = new method2();
                Object arglist[] = new Object[2];
                arglist[0] = new Integer(37);
                arglist[1] = new Integer(47);
                Object retobj 
                  = meth.invoke(methobj, arglist);
                Integer retval = (Integer)retobj;
                System.out.println(retval.intValue());
             }
             catch (Throwable e) {
                System.err.println(e);
             }
          }
       }
    

    另见

    【讨论】:

    • 我如何触发默认构造函数或该类中的某些方法?
    • 对不起,我忘了添加关于谷歌网络工具包和东西,我使用谷歌网络工具包,它不支持反射。
    • 看看herehere还有this
    • 我想谈谈哲学! Class是Java中的一种数据类型吗?
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      使用

      void callClass(Class classObject)
      {
         //do something with class
      }
      

      Class 也是一个 Java 对象,所以你可以通过它的类型来引用它。

      official documentation了解更多信息。

      【讨论】:

        【解决方案4】:

        【讨论】:

        • OP 明确表示他正在使用不支持反射的 GWT
        • 这个问题在我回答很久之后才被编辑。原始问题不包含该提示。顺便说一句,公认的答案也指的是反射。
        【解决方案5】:

        这种事情并不容易。这是一个调用静态方法的方法:

        public static Object callStaticMethod(
            // class that contains the static method
            final Class<?> clazz,
            // method name
            final String methodName,
            // optional method parameters
            final Object... parameters) throws Exception{
            for(final Method method : clazz.getMethods()){
                if(method.getName().equals(methodName)){
                    final Class<?>[] paramTypes = method.getParameterTypes();
                    if(parameters.length != paramTypes.length){
                        continue;
                    }
                    boolean compatible = true;
                    for(int i = 0; i < paramTypes.length; i++){
                        final Class<?> paramType = paramTypes[i];
                        final Object param = parameters[i];
                        if(param != null && !paramType.isInstance(param)){
                            compatible = false;
                            break;
                        }
        
                    }
                    if(compatible){
                        return method.invoke(/* static invocation */null,
                            parameters);
                    }
                }
            }
            throw new NoSuchMethodException(methodName);
        }
        

        更新: 等等,我刚刚在问题上看到了 gwt 标签。您不能在 GWT 中使用反射

        【讨论】:

          【解决方案6】:

          正如你所说,GWT 不支持反射。您应该使用延迟绑定而不是反射,或使用第三方库(例如 gwt-ent)在 gwt 层进行反射支持。

          【讨论】:

            【解决方案7】:

            我不确定您要完成什么,但您可能要考虑通过课程可能不是您真正需要做的事情。在许多情况下,像这样处理 Class 很容易封装在某种类型的工厂模式中,并且通过接口完成使用。这是关于该模式的数十篇文章之一:http://today.java.net/pub/a/today/2005/03/09/factory.html

            在工厂中使用类可以通过多种方式来完成,最明显的是通过拥有一个包含实现所需接口的类的名称的配置文件。然后工厂可以从类路径中找到该类,并将其构造为指定接口的对象。

            【讨论】:

              【解决方案8】:
              public void callingMethod(Class neededClass) {
                  //Cast the class to the class you need
                  //and call your method in the class
                  ((ClassBeingCalled)neededClass).methodOfClass();
              }
              

              要调用方法,你可以这样调用:

              callingMethod(ClassBeingCalled.class);
              

              【讨论】:

              • 提问者也想使用类的构造函数。这并不容易,而且没有人在这里解决它。这篇文章提供了一个选项(阅读所有 cmets,因为接受的答案不起作用):stackoverflow.com/questions/234600/…。但是,它非常混乱,并且您收到的编译器警告表明他们不希望人们使用 Java 来执行此操作。在 Python 中更容易:)
              【解决方案9】:

              类作为参数。示例。

              三类:

              class TestCar {
              
                  private int UnlockCode = 111;
                  protected boolean hasAirCondition = true;
                  String brand = "Ford";
                  public String licensePlate = "Arizona 111";
              }
              

              --

              class Terminal {
              
              public void hackCar(TestCar car) {
                   System.out.println(car.hasAirCondition);
                   System.out.println(car.licensePlate);
                   System.out.println(car.brand);
                   }
              }
              

              --

              class Story {
              
                  public static void main(String args[]) {
                      TestCar testCar = new TestCar();
                      Terminal terminal = new Terminal();
                      terminal.hackCar(testCar);
                  }
              
              }
              

              在类终端方法 hackCar() 中,将类 TestCar 作为参数。

              【讨论】:

              • 呃,不,它正在获取 TestCar 的实例
              【解决方案10】:

              构造你的方法来接受它-

              public <T> void printClassNameAndCreateList(Class<T> className){
                  //example access 1
                  System.out.print(className.getName());
              
                  //example access 2
                  ArrayList<T> list = new ArrayList<T>();
                  //note that if you create a list this way, you will have to cast input
                  list.add((T)nameOfObject);
              }
              

              调用方法-

              printClassNameAndCreateList(SomeClass.class);
              

              你还可以限制类的类型,例如,这是我制作的库中的方法之一-

              protected Class postExceptionActivityIn;
              
              protected <T extends PostExceptionActivity>  void  setPostExceptionActivityIn(Class <T> postExceptionActivityIn) {
                  this.postExceptionActivityIn = postExceptionActivityIn;
              }
              

              有关更多信息,请搜索反射和泛型。

              【讨论】:

                【解决方案11】:

                添加 T 作为返回类型对我有用。 Ex 与 json 反序列化

                 public static <T> T fromJson(String json, Class<T> classOfT){
                     return gson().fromJson(json, classOfT);
                 }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-01-15
                  • 2011-02-21
                  • 1970-01-01
                  • 2018-05-17
                  • 2012-10-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多