简体   繁体   English

通过反射 API 使 Java 类成为非最终类

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM