Java 正在Drools中更新现有枚举常量的值

Java 正在Drools中更新现有枚举常量的值,java,enums,drools,Java,Enums,Drools,我有下面的枚举结构,我必须更改第二个参数的值THREAT。该应用程序几乎已经开发完毕,并且在很大程度上依赖于枚举类型,并且该类型无法更改(因为有大量的枚举变量)。当应用程序重新启动时,我需要那里的默认值。有没有什么方法可以动态更改威胁的值 enum TraceLevel { APP_DOS("as", ""), APP_DOS1("as", ""), APP_DOS2("as",

我有下面的枚举结构,我必须更改第二个参数的值THREAT。该应用程序几乎已经开发完毕,并且在很大程度上依赖于枚举类型,并且该类型无法更改(因为有大量的枚举变量)。当应用程序重新启动时,我需要那里的默认值。有没有什么方法可以动态更改威胁的值

enum TraceLevel {
   APP_DOS("as", ""),
   APP_DOS1("as", ""),
   APP_DOS2("as", ""),
   APP_DOS3("as", ""),
   APP_DOS4("as", "");
   String NAME;
   String THREAT;

   private TraceLevel(String name, String threat) {
      this.NAME = name;
      this.THREAT = threat;
   }
}
更新1
根据评论的不同,我想我应该进一步更新这个问题。我基本上是在drools规则引擎上工作,在这里我有枚举常量。这里的声明并不真正像Java。所以,我不知道该怎么做。这是流口水的特定模式

declare enum AttackCategory
APP_DOS("as", ""),
APP_DOS1("as", ""),
APP_DOS2("as", ""),
APP_DOS3("as", ""),
APP_DOS4("as", "");
value : String
threat: String

end

正如许多问题评论所说,您试图以一种非设计或预期的方式使用枚举。与大多数情况下发生的情况一样,您可能会强制它工作,但您会遇到额外的问题。正确的答案是回到绘图板,正如他们所说的,并提出一个解决方案,该解决方案不试图强制枚举具有类行为


枚举方式(错误) 要更改枚举上的值,请向声明中添加setter。在Java中,这是这样做的:

enum TraceLevel{
应用程序(如“,”)。。。;
字符串名;
字符串威胁;
private TraceLevel(字符串名称、字符串威胁){
this.NAME=名称;
这个。威胁=威胁;
}
公共字符串getThreat(){返回this.NAME;}
public void setThreat(字符串名称){this.name=name;}
}
(还有一点小注释——“name”和“threat”的变量不应完全大写。它们应遵循常规变量的命名约定。)

另一方面,如果您使用的是Drools,则不会在这些结构上创建方法,而是按照bean约定生成getter和setter。正如您所指出的,这些约定不会在枚举上生成这样的方法(这类约定应该暗示您试图以错误的方式使用它们)

所以,如果必须使用枚举,则必须用Java声明它们


替代方法:课堂 您的用例似乎只是被美化了的常量,所以为什么不将其作为替代方法使用呢?声明一个包含三个字符串变量(name、thread、id)的类,然后在规则中将它们全部插入工作内存,并应用默认值。当您确实需要使用它们时,您可以根据需要在内存中更新它们

declare TraceLevel
  id: String
  name: String
  threat: String
end

rule "Prepare default trace levels"
when
  not( TraceLevel() )
then
  insert( new TraceLevel("APP_DOS", "as", "") ) // equivalent to TraceLevel.APP_DOS
  insert( new TraceLevel("APP_DOS2", "as", "") )
  // etc.
end

rule "Example rule which needs to update a Threat value"
when
  $traceLevel: TraceLevel( id == "APP_DOS" )
then
  modify( $traceLevel ) { threat = "new threat value" }
end
第一条规则“准备默认跟踪级别”将默认级别插入工作内存。此时,工作内存包含一组功能上与枚举值相同的对象。由于它们位于工作内存中,因此现在可用于任何后续评估的规则

请注意,此规则的条件非常简单,并验证工作内存中没有预先存在的TraceLevel实例——如果出于某种原因触发完全重新计算,则此规则不会执行多次

第二个示例规则显示了如何使用
modify
更新“威胁”值


在所有情况下,我都添加了一个“id”字段,以便您可以识别特定的TraceLevel实例。这些是TraceLevel枚举名称的等效项(例如,TraceLevel.APP_-DOS->id=“APP_-DOS”)。第二个示例显示了如何利用此ID获取特定的TraceLevel实例。

是的,有一种方法:使用setter。您尝试过什么吗?在枚举中使用可变字段是一个非常糟糕的主意,但是Java语言中没有任何东西阻止您这么做。您可以添加一个setter并修改字段。这听起来像是XY问题。在这里,你真正想要完成的是什么?改变枚举的状态几乎总是一个非常非常糟糕的主意。我刚刚更新了这个问题。请你现在看看好吗@F1SH您刚刚发现您想要更改枚举常量的内部结构,这与“常量”的概念相矛盾。这要么需要彻底的重构(即使“应用程序几乎已经开发完毕”),要么从长远来看需要大麻烦。