3

我希望能够在具有该方法的对象上调用“getProgram”,而不知道它们属于哪个类。我知道我应该在这里使用一个接口,但是我正在使用其他人的代码并且无法重新设计我正在使用的类。我认为 BeanUtils.getProperty 可能会帮助我,但它似乎只返回字符串。有没有类似 Beanutils.getProperty 的东西会返回一个可转换的对象?或者另一种更聪明的方式来处理两个不共享接口的相似类?谢谢,-摩根

4

7 回答 7

5

使用 PropertyUtils(来自 apache commons-beanutils)而不是 BeanUtils。

它有一个 getProperty(Object bean, String name) 方法,该方法返回一个 Object 而不是 String。

有关更多信息,请参阅JavaDoc

于 2009-01-27T16:32:18.650 回答
2

只需为此使用反射......以下示例显示了如何在没有公共接口的对象上执行此操作。

    public static void main(String[] args) throws Exception {
    doSomething(new A());
    doSomething(new B());
}

private static void doSomething(Object object) throws Exception {
    Method m = object.getClass().getMethod("doSomething", (Class[])null);
    m.invoke(object, (Object[])null);
}

private static class A {
    public void doSomething() {
        System.out.println("I'm doing it already!");
    }
}

private static class B {
    public void doSomething() {
        System.out.println("I'm doing it too!");
    }
}
于 2009-01-27T16:14:03.977 回答
0

请参阅反射 API

使用 Class.getMethod()(或 getMethods())找到合适的方法并调用它。

于 2009-01-27T16:11:41.157 回答
0

大概您有有限数量的类实现此方法,您可以直接链接到它们。所以你不需要反思。反射是邪恶的。

假设您有一组具有该方法的类:

public class LibA { public Program getProgram() { return program; } ... };
public class LibB { public Program getProgram() { return program; } ... };
...

然后你只需要 instanceof/cast 对。你可以把它放在一个方法中,这样你只需要做一次。

public static Program getProgram(Object obj) {
    if        (obj instanceof LibA) {
        return              ((LibA)obj).getProgram();
    } else if (obj instanceof LibB) {
        return              ((LibB)obj).getProgram();
    } else {
        throw new IllegalArgumentException(obj+" doesn't have a known getProgram");
            // Or an appropriate application exception.
    }
}

或者,您可能想要使用适配器:

public interface ProgramContainer { 
    Program getProgram();
    ...
}

public class LibAContainer implements ProgramContainer {
    private final LibA libA;
    public LibAContainer(LibA libA) {
        this.libA = libA;
    }
    public Program getProgram() {
        return libA.getProgram();
    }
    ...
}
于 2009-01-27T16:39:08.340 回答
0

一个非常简单的解决方案:使用实现接口的委托:

interface GetProgram
{
    String getProgram ();
}

class AWrapper implements GetProgram
{
    A a;
    public AWrapper (A a) { this.a = a;
    String getProgram () { return a.getProgram(); }
}

现在您可以在代码中使用该接口,而无需触及原始类。

缺点:如果您的 A 是在您无法触及的某个地方创建的,则此方法效果不佳。如果 A 在您的控制下创建一次并且您可以立即包装它,则效果最好。

于 2009-01-27T16:59:57.720 回答
0

如果您有 Java 5+,则版本略短

public static void main(String[] args) throws Exception {
    System.out.println(invoke("toString", new A());
    System.out.println(invoke("toString", new B());
}

private static <R> R invoke(Object object, String methodName) throws Exception {
    return (R) object.getClass().getMethod(methodName).invoke(object);
}
于 2009-01-27T19:56:52.513 回答
-1

java.beans.Expression会这样做,只要该方法在接收器的具体类中是可访问的。

public static void main(String[] args) throws Exception {
    new Expression(new A(), "doSomething", null).getValue();
    new Expression(new B(), "doSomething", null).getValue();
}

public static class A {
    public void doSomething() {
            System.out.println("I'm doing it already!");
    }
}

public static class B {
    public void doSomething() {
            System.out.println("I'm doing it too!");
    }
}
于 2009-01-27T16:22:31.947 回答