【问题标题】:In Java, can I create an instance of an anonymous subclass from a Class object?在 Java 中,我可以从 Class 对象创建匿名子类的实例吗?
【发布时间】:2009-08-20 14:12:13
【问题描述】:

我有一个工厂方法可以创建用于单元测试的对象。这些对象都派生自同一个基类:

public static <T extends BaseEntity> T modMake(Class<T> clazz)
{
    try {
        return clazz.newInstance();
    } catch (InstantiationException e) {
        // Should never happen
        throw new AssertionError(e);
    } catch (IllegalAccessException e) {
        // Should never happen
        throw new AssertionError(e);
    }
}

现在我想重写该基类中的 getter 方法,但仅用于测试。我通常会使用匿名类来做到这一点,例如(NodeBaseEntity 的子类型之一):

public static Node nodMake()
{
    return new Node() {
        @Override
        public long ixGet() { return 1; }
    };
}

我也可以在函数中使用Class 参数来做到这一点吗?

【问题讨论】:

    标签: java reflection mocking


    【解决方案1】:

    丢失您的工厂方法并使用类似EasyMock 的模拟API 来实现您描述的行为。

    您的代码最终会是这样的:

    long returnValue = 12;
    
    Node nodeMock = createMock(Node.class);
    expect(nodeMock.ixGet()).andReturn(returnValue);
    replay(nodeMock);
    
    //add test code here
    
    verify(nodeMock);
    

    回答 Hanno 关于其工作原理的问题:

    这取决于你是模拟一个接口还是一个类。

    接口 的情况很简单(代码方面),它使用所谓的动态代理,它是核心 Java 的一部分。

    class 的情况下,它正在执行@Jonathan 在他的回答中提到的字节码操作,就在一个不错的 API 后面。

    上述两种机制都允许拦截方法调用,EasyMock 只是根据您设置的期望做出响应。

    【讨论】:

    • 有趣。我还没有像这样使用过 Java。
    • 我现在实际上在使用 EasyMock,它很不错。谢谢!
    【解决方案2】:

    我认为没有任何方法可以做到这一点。如果你真的需要走这条路,你可能需要研究字节码操纵器。 Javassist 和 BCEL 是几个选择。

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多