【问题标题】:Can not remove the modifier of final class不能去掉final类的修饰符
【发布时间】:2013-05-24 09:04:48
【问题描述】:

我想删除 1 类的最终关键词。我正在为这个类编写 Junit,我调用 Mockito 的 spy 来模拟一个方法来返回一个涵盖所有情况的期望值。

使用后:

CtClass ctClazz = ClassPool.getDefault().get(Livre.class.getName());
ctClazz.setModifiers(ctClazz.getModifiers() & ~Modifier.FINAL);
ctClazz.writeFile();

这个类的修饰符是17,但我认为应该是1(public)。

我得到了错误:

Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class mediatheque.document.Livre
    at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
    at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
    at org.powermock.api.easymock.internal.signedsupport.SignedSupportingClassProxyFactory.createProxy(SignedSupportingClassProxyFactory.java:147)
    at org.easymock.internal.MocksControl.createMock(MocksControl.java:40)
    at org.easymock.classextension.internal.MocksClassControl.createMock(MocksClassControl.java:43)
    at org.powermock.api.easymock.PowerMock.doMock(PowerMock.java:2076)
    at org.powermock.api.easymock.PowerMock.createMock(PowerMock.java:79)
    at org.powermock.api.easymock.PowerMock.createPartialMock(PowerMock.java:765)
    at test.mediatheque.document.TestDocument.testRestituer_With_Exception3(TestDocument.java:379)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$2.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:217)
    ... 19 more

这个最终类从一个抽象类扩展而来。

感谢您的帮助。

【问题讨论】:

    标签: junit


    【解决方案1】:

    您不能扩展(子类)final 类。如果您确实需要这样做(无论是为了测试还是因为您确实需要覆盖其他人库中的方法),您将不得不“分叉”该类。将其内容复制到一个新类中(更新包声明和类引用),并删除final 名称​​那里。然后,您可以随心所欲地扩展它。我最近在 Spring Security 方面非常有效地使用了这种方法。

    【讨论】:

    • 我的意思是这个类从一个抽象类扩展而来。它是一个子类。它没有被任何类扩展。
    • 我明白,但是 Junit 正在有效地扩展它(如果我没记错的话,通过代理),这就是抛出异常的原因。复制('fork')类,将你的调用指向分叉的版本,然后你的测试就可以正常运行了。
    • 你能给我举个例子吗?对不起,我不太了解你
    • 嗨,现在我明白了。你的意思是我应该将这个类复制到另一个类并删除 final 修饰符并为新类编写测试用例?类的逻辑还保留吗?
    猜你喜欢
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 2011-01-11
    • 2019-06-29
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    相关资源
    最近更新 更多