【问题标题】:Invoke a method of an object of type Class调用 Class 类型对象的方法
【发布时间】:2015-03-19 09:42:20
【问题描述】:

我会尽量设置简单,因为它也让我感到困惑。

我有一个方法返回 Class 类型的对象,即

public Class foo(){...}

当我调用此方法时,我将结果保存在 Class 类型的变量中,即

Class obj = new foo();

foo() 可以返回许多不同的类,但它们都包含相同的方法bar()

如何从我的obj 变量调用该方法?

我尝试了obj.bar(),但 IDE 似乎不喜欢它。我明白了

错误:(59, 34) 错误:找不到符号方法bar()

【问题讨论】:

  • Class obj = new foo() 永远不会有效,除非您谈论的 Class 类型与 java.lang.Class 不同。一个简短但完整的程序来演示这个问题会让这一切变得更加清晰。
  • 你必须使用((foof)obj).bar()
  • 正如 Jon Skeet 所说,Class obj = new foo() 无效。你可能想做Foo obj = foo().newInstance(),然后obj.bar()

标签: java class object methods


【解决方案1】:

您似乎想对行为进行分组,这就是 Java interfaces 所做的:

interface Barer {
    String bar();
}

class Foo implements Barer {
    String bar() {
        return "I'm a Foo";
    }
}

class Fooz implements Barer {
    String bar() {
        return "I'm a Fooz";
    }
}

然后在你的代码中你可以有类似的东西:

Barer obj;

if (something) {
    obj = new Foo();
} else {
    obj = new Fooz();
}

obj.bar()

实际上将构造函数的返回值存储在Class 对象中毫无意义。


如果您确实需要一个 Class 对象(请记住,它只会指向 Class,而不是您创建的实例),您可以使用 Java reflection

Class obj = new foo();
Method method = obj.getDeclaredMethod("bar");
method.invoke(null);

【讨论】:

  • 这可能是最好的方法。如果出于任何原因不得不使用丑陋的黑客技术(但可能应该调整其代码不这样做,而是使用上面描述的接口): Method m = obj.getDeclaredMethod("bar", null);对象 o = m.invoke(null, null);
  • 是的,我刚刚添加了那个案例;)
  • 你比我快:)。此外,正如在问题的 cmets 中所注意到的,Class obj = new foo(); 应替换为 Class obj = foo();
【解决方案2】:

如果方法 foo() 返回 Class,这意味着它不返回要调用 bar() 方法的对象的实际实例,而是返回类本身,因此无法调用方法 bar() Class as Class.class 没有方法栏。

在您的代码示例中存在一些错误

Class obj = new foo();

关键字 new 表示您正在创建一个类的新实例,而不是调用对象的方法。


事实上,正确的方法是使用接口。

声明一个接口,而不是从 foo 方法返回 Class,

public interface MyInterface {
  public void bar();
}

并让 foo() 返回 MyInterface 而不是 Class。

那你就可以了

MyInterface obj = tmp.foo();
obj.bar()

【讨论】:

    【解决方案3】:

    如果所有返回值都是实现相同方法的类的对象,则应在单独的接口中声明该方法并让它们实现。稍后您可以使用通用通配符,如<? extends BarInterface> 或将返回类型更改为BarInterface

    public interface BarInterface{
        public void bar();
    }
    

    public <T extends BarInterface> foo(){...}
    

    public BarInterface foo() {...}
    

    【讨论】:

      猜你喜欢
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      相关资源
      最近更新 更多