6

我有一个类似于以下的 Java 类:

public final class Node {
    public Node() {}
}

我已经学会了如何通过反射 API 更改“最终”字段的可访问性,但这也适用于类吗?我可以在运行时将最终类变成非最终类吗?

4

3 回答 3

4

您可以使用 ASM 之类的库重新编写类文件。

在运行时更改类的状态可能没有意义final,因为它在编译时需要是非最终的才能编译子类。

于 2012-05-23T16:18:33.620 回答
0

我不明白这是如何工作的,因为编译器会检查你试图在编译时创建的类是否非最终类。如果你试图继承它,你会得到一个错误。

如果你好奇,我认为问这个问题很好,但要问自己的更大问题是你为什么要这样做?反射允许你做很多事情来绕过 final、private 等,但这并不意味着它是一个好主意。如果第 3 方库的设计者认为 final 是一个好主意,那么建议您尊重这一点。

于 2012-05-23T16:19:43.963 回答
0

编辑:感谢@kriegaex 的评论。'accessFlags' 字段仅存在于 Android SDK 的 Class 类实现中。因此,除非您正在为 Android 开发,否则此解决方案将不适合您,因为首先不存在这样的字段。

以下是通过删除“final”修饰符使类可扩展的方法:

Class classClass = Class.class;

Field accessFlagsField = classClass.getDeclaredField("accessFlags");

accessFlagsField.setAccessible(true);

Class nodeClass = Node.class;

accessFlagsField.setInt(nodeClass, nodeClass.getModifiers() & ~Modifier.FINAL);

我不同意上面的答案。有人可能想要删除“final”修饰符以在运行时通过使用“ASM”或“byte-buddy”等库来扩展类。我同意,如果它是最终类,这可能是有充分理由的,但自定义业务逻辑可能需要这样做。

于 2020-04-02T23:55:03.897 回答