我有一个类似以下的Java类:
public final class Node {
public Node() {}
}
我已经学会了如何通过反射应用编程接口改变“最终”字段的可访问性,但是这对类也是可能的吗?我可以在运行时将最终类变成非最终类吗?
编辑:感谢@kriegaex的评论。“访问标志”字段只存在于Android软件开发工具包中的类实现中。因此,除非你是为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);
我不同意上面的答案。有人可能想删除“最终”修饰符,以便在运行时通过使用“ASM”或像“字节伙伴”这样的库来扩展类。我同意如果它是一个最终类,它可能是有充分理由的,但是定制的业务逻辑可能需要这样做。
我看不出这是如何工作的,因为编译器会检查您试图在编译时使其成为非final的类。如果你试图从中继承,你会得到一个错误。
我认为如果你好奇的话可以问这个问题,但更大的问题是你为什么要这样做?反思可以让你做很多事情来绕过期末考试、私人考试等,但这并不意味着这是个好主意。如果第三方图书馆的设计师认为final是个好主意,你最好尊重这一点。
可以使用ASM之类的库重新编写类文件。
在运行时更改类的final
状态可能没有意义,因为编译子类时它需要是非final的。
问题内容: 我有两个字符串: 我通过反思上课 我想要aClass扩展b,例如: 如何实现呢? 如何获得okClass? 谢谢! 问题答案: 除了使用仅通过接口工作的JDK动态代理外,您还可以使用CGLIB或javassist在运行时扩展类。
问题内容: 请参考下面的代码。运行代码时,我可以更改最终非静态变量的值。但是,如果我尝试更改最终静态变量的值,则会抛出异常。 我的问题是,为什么在非静态最终变量也不会抛出异常,反之亦然。为什么会有所不同? 问题答案: 该解决方案并非没有缺点,它可能无法在所有情况下都有效: 如果在字段声明中将字段初始化为编译时常量,则对该字段的更改可能不可见,因为该最终字段的使用会在编译时用编译时常量替换。 另一个
通过下列任意一个方法访问成员变量时将返回 Field 类型的对象或数组。 getFields() getField(String name) getDeclaredFields() getDeclaredField(String name) 上述方法返回的 Field 对象代表一个成员变量。例如,要访问一个名称为 price 的成员变量,示例代码如下: Field 类的常用方法如表 1 所示 表1
我读了一大堆这么多的问题,但我似乎找不到答案。 我有以下课程: 在其他地方,我试图访问这些字符串: 为什么我会得到一个IllegalAccess异常?如果我删除field.get行,我可以在LogCat中看到以下行: 参考资料: 使用反射在Java中获取成员变量值的陷阱 反射:通过反射加载的类中的常量变量 通过反射访问Java静态最终ivar值
我有一个. JAR文件,里面有很多类。第一,我需要的设置为final,所以我不能扩展它。有一种方法,我基本上必须扩展和修复,否则一切都会崩溃。我该怎么做呢?我知道反射和Javassist可以用来做这件事,但是我不知道怎么做。其他任何工具也是可以接受的,只要能用就行。
主要内容:结构体字段类型,获取成员反射信息任意值通过 reflect.TypeOf() 获得反射对象信息后,如果它的类型是结构体,可以通过反射值对象(reflect.Type)的 NumField() 和 Field() 方法获得结构体成员的详细信息。与成员获取相关的 reflect.Type 的方法如下表所示。 结构体成员访问的方法列表 方法 说明 Field(i int) StructField 根据索引,返回索引对应的结构体字段的信