Reflection AspectJ-可以扩展枚举';s值多少?

Reflection AspectJ-可以扩展枚举';s值多少?,reflection,enums,aspectj,Reflection,Enums,Aspectj,假设我有一个枚举 public enum E {A,B,C} 是否可以通过AspectJ添加另一个值,例如D 在谷歌搜索之后,似乎有一种方法可以破解私有静态字段$VALUES,然后通过反射调用构造函数(String,int),但似乎不再使用1.7了 以下是几个链接: (由@WimDeblauwe提供) 这是:实际上,我建议您重构源代码,可能会在每个枚举值中添加一组有效的区域ID。如果您使用Git而不是像SVN这样的老式SCM工具,那么对于后续的合并来说,这应该足够简单 如果将来命令列表是动态的

假设我有一个枚举

public enum E {A,B,C}
是否可以通过AspectJ添加另一个值,例如
D

在谷歌搜索之后,似乎有一种方法可以破解私有静态字段
$VALUES
,然后通过反射调用构造函数(String,int),但似乎不再使用1.7了

以下是几个链接: (由@WimDeblauwe提供)


这是:

实际上,我建议您重构源代码,可能会在每个枚举值中添加一组有效的区域ID。如果您使用Git而不是像SVN这样的老式SCM工具,那么对于后续的合并来说,这应该足够简单

如果将来命令列表是动态的,那么完全使用动态数据结构而不是枚举可能更有意义。但这应该进入上游代码库。我相信开发者会接受一个好的补丁或拉请求,如果准备干净的话

记住:试图避免重构通常是一种难闻的气味,一种疾病的症状,而不是解决方案。我更喜欢有症状的解决办法。干净的代码规则和软件工艺态度要求这一点


说到这里,现在你可以做些什么了。它应该在JDK 7/8下工作,我在上找到了它(请确保添加本文下面评论中提到的错误修复)

枚举扩展程序实用程序:

package de.scrum\u master.util;
导入java.lang.reflect.AccessibleObject;
导入java.lang.reflect.Array;
导入java.lang.reflect.Field;
导入java.lang.reflect.Modifier;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入sun.reflect.constructor或accessor;
导入sun.reflect.FieldAccessor;
导入sun.reflect.ReflectionFactory;
公共类DynamicXtender{
私有静态反射工厂反射工厂=
ReflectionFactory.getReflectionFactory();
私有静态void setFailsafeFieldValue(字段、对象目标、对象值)
抛出NoSuchFieldException、IllegalAccessException
{
//让我们把这片土地弄清楚
字段。setAccessible(true);
//接下来,我们将字段实例中的修饰符更改为
//不再是最终的,因此欺骗反射到
//让我们修改静态final字段
字段修饰符字段=Field.class.getDeclaredField(“修饰符”);
modifiersField.setAccessible(true);
int modifiers=modifiersField.getInt(字段);
//将修饰符int中的最后一位留空
修饰符&=~Modifier.FINAL;
修饰符字段.setInt(字段,修饰符);
FieldAccessor fa=reflectionFactory.newFieldAccessor(字段,false);
固定资产(目标、价值);
}
私有静态void blankField(类enumClass,字符串字段名)
抛出NoSuchFieldException、IlleGalaceSException
{
for(字段:Class.Class.getDeclaredFields()){
if(field.getName().contains(fieldName)){
setAccessibleObject.setAccessible(新字段[]{Field},true);
setFailsafeFieldValue(字段,enumClass,null);
打破
}
}
}
私有静态void cleanEnumCache(类enumClass)
抛出NoSuchFieldException、IllegalAccessException
{
blankField(enumClass,“enumConstantDirectory”);//Sun(Oracle?!?)JDK 1.5/6
blankField(enumClass,“enumConstants”);//IBM JDK
}
私有静态构造函数Accessor getConstructorAccessor(类enumClass,类[]附加参数类型)
抛出NoSuchMethodException
{
Class[]parameterTypes=新类[additionalParameterTypes.length+2];
参数类型[0]=String.class;
参数类型[1]=int.class;
数组复制(additionalParameterTypes,0,parameterTypes,2,additionalParameterTypes.length);
返回reflectionFactory.newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
}
私有静态对象makeEnum(类enumClass、字符串值、整数序号、类[]附加类型、对象[]附加值)
抛出异常
{
Object[]parms=新对象[additionalValues.length+2];
parms[0]=值;
parms[1]=整数.valueOf(序数);
数组复制(additionalValues,0,parms,2,additionalValues.length);
返回enumClass.cast(getConstructorAccessor(enumClass,additionalTypes).newInstance(parms));
}
/**
*将枚举实例添加到作为参数给定的枚举类
*
*@param枚举的类型(隐式)
*@param enumType要修改的枚举的类
*@param enumName要添加到类中的新枚举实例的名称
*/
@抑制警告(“未选中”)

public static不是一个确切的答案,但也许这有帮助:似乎不再工作了。
clazz.getDeclaredConstructor(String.class,int.class)
不工作。实际上
clazz.getConstructors()
clazz
是一个枚举时,返回一个空数组。我想知道为什么这么多人认为AspectJ是一个黑客工具。它是一个干净的代码工具,通过模块产生横切关注点。即使你想要的东西通过反射以某种方式工作,为什么你要操纵枚举?通过设计枚举,它是某种枚举的常量列表关于价值观。通过打破设计原则,你得到了什么?稳定性?可维护性?还是什么都没有用?很抱歉,但我无法抗拒。@kriegaex问题是,我有一个由另一群人开发的游戏的源代码。我们需要在我们地区运行它之前进行一些修改。所以我需要一个“干净”的方法来解决这个问题进行这些更改,这样我就不会因为将原始开发团队的未来版本与我自己的“hack”合并而感到非常痛苦。所以我认为AspectJ是一个不错的选择。至于这个枚举,它是一个