我有一个类似于以下的 Java 类:
public final class Node {
public Node() {}
}
我已经学会了如何通过反射 API 更改“最终”字段的可访问性,但这也适用于类吗?我可以在运行时将最终类变成非最终类吗?
我有一个类似于以下的 Java 类:
public final class Node {
public Node() {}
}
我已经学会了如何通过反射 API 更改“最终”字段的可访问性,但这也适用于类吗?我可以在运行时将最终类变成非最终类吗?
您可以使用 ASM 之类的库重新编写类文件。
在运行时更改类的状态可能没有意义final
,因为它在编译时需要是非最终的才能编译子类。
我不明白这是如何工作的,因为编译器会检查你试图在编译时创建的类是否非最终类。如果你试图继承它,你会得到一个错误。
如果你好奇,我认为问这个问题很好,但要问自己的更大问题是你为什么要这样做?反射允许你做很多事情来绕过 final、private 等,但这并不意味着它是一个好主意。如果第 3 方库的设计者认为 final 是一个好主意,那么建议您尊重这一点。
编辑:感谢@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”等库来扩展类。我同意,如果它是最终类,这可能是有充分理由的,但自定义业务逻辑可能需要这样做。