[英]Making Java Class non-final via Reflection API
I have a Java class similar to the following one:我有一个类似于以下的 Java 类:
public final class Node {
public Node() {}
}
I have learned already how to change change the accessibility of 'final' fields via the reflection API, but is this also possible for classes?我已经学会了如何通过反射 API 更改“最终”字段的可访问性,但这也适用于类吗? Can I turn a final class into a non-final class at runtime?
我可以在运行时将 final 类变成非 final 类吗?
You can re-write a class file using a library like ASM.您可以使用 ASM 之类的库重写类文件。
There may be no point changing the final
status of a class at runtime as it needs to be non-final at compile time to compile a sub-class.在运行时更改类的
final
状态可能没有意义,因为它需要在编译时为非最终状态才能编译子类。
I don't see how this can work, because the compiler will check to see if the class you're trying to make non-final at compile time.我不知道这是如何工作的,因为编译器会检查您在编译时尝试创建的类是否为非最终类。 You'll get an error if you try to inherit from it.
如果您尝试继承它,您将收到错误消息。
I think it's fine to ask the question if you're curious, but the larger question to ask yourself is why do you want to do this?我认为如果你好奇,问这个问题很好,但要问自己更大的问题是你为什么要这样做? Reflection allows you to do a lot of things to get around final, private, etc., but that doesn't mean it's a good idea.
反射允许你做很多事情来解决 final、private 等问题,但这并不意味着它是一个好主意。 If the designer of a 3rd party library thought that final was a good idea, you might be well advised to honor that.
如果第 3 方库的设计者认为 final 是一个好主意,那么您可能会被建议尊重这一点。
Edit: Thanks to the comment of @kriegaex.编辑:感谢@kriegaex 的评论。 'accessFlags' field only exists in Class class implementation in Android SDK.
'accessFlags' 字段只存在于 Android SDK 的 Class 类实现中。 Therefore, unless you are developing for Android, this solution will not work for you since such a field does not exist in the first place.
因此,除非您正在为 Android 开发,否则此解决方案将不适合您,因为这样的字段首先不存在。
Here is how you can make the class extendable by removing the 'final' modifier:以下是通过删除“final”修饰符使类可扩展的方法:
Class classClass = Class.class;
Field accessFlagsField = classClass.getDeclaredField("accessFlags");
accessFlagsField.setAccessible(true);
Class nodeClass = Node.class;
accessFlagsField.setInt(nodeClass, nodeClass.getModifiers() & ~Modifier.FINAL);
I do not agree with the answers above.我不同意上面的答案。 One might want to remove the 'final' modifier to extend the class during runtime by using 'ASM' or libraries like 'byte-buddy'.
人们可能希望通过使用“ASM”或“byte-buddy”之类的库来删除“final”修饰符以在运行时扩展类。 I agree that if it is a final class, it is probably for a good reason but custom business logic may require to do so.
我同意,如果它是 final 类,它可能是有充分理由的,但自定义业务逻辑可能需要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.