我知道在java中如果我想使用反射来设置最终字段我可以更改该字段的访问修饰符,如下所示:
Field field = clazz.getDeclaredField("someField");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Run Code Online (Sandbox Code Playgroud)
我很难在 kotlin 中实现同样的目标。问题在于最后一行的按位运算符modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL)
。诚然,我一般对按位运算符有些无知,也不知道 kotlin 的等价物。
当我尝试在 Kotlin 测试中使用 JUnit 5 Assertions.fail 时,我编译失败,因为无法推断参数 V:
import org.junit.jupiter.api.Assertions.fail
internal class MyTests {
@Test
fun simpleTest() {
fail("Does not compile")
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这个问题的一个简单解决方案是:
import org.junit.jupiter.api.Assertions.fail
internal class MyTests {
@Test
fun simpleTest() {
val result: Any = fail("Compiles")
}
}
Run Code Online (Sandbox Code Playgroud)
但是我不想在我的代码中创建一个未使用的值。有没有办法定义类型而不必声明 val?另外,为什么在 Kotlin 中会发生这种情况?Java 对泛型没有这样的问题:
import org.junit.jupiter.api.Assertions.fail;
class MyJavaTests {
@Test
public void simpleTest() {
fail("Compiles);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我在发布问题后立即发现解决方案是参数化调用:
import org.junit.jupiter.api.Assertions.fail
internal class MyTests {
@Test
fun simpleTest() {
fail<Any>("Does not compile")
}
}
Run Code Online (Sandbox Code Playgroud)
但是仍然愿意接受可以解释为什么我需要在 kotlin 中执行此操作的答案。