枚举作为Java中常量的替换

枚举作为Java中常量的替换,java,enums,constants,Java,Enums,Constants,有一天我听说我们应该使用枚举而不是常量。 在所有情况下都可能吗枚举是否替换常量 在下面的示例中,我在常量文件中定义了常量,ConstantTest使用它们 public final class Constants { private Constants(){ } public static final String ACCOUNT="Account"; public static final String EVENT_ITEM ="EventItem"; public static fina

有一天我听说我们应该使用枚举而不是常量。 在所有情况下都可能吗枚举是否替换常量

在下面的示例中,我在常量文件中定义了常量,ConstantTest使用它们

public final class Constants {

private Constants(){

}
public static final String ACCOUNT="Account";
public static final String EVENT_ITEM ="EventItem";
public static final int MULTIPLIER_ONE = 1;
public static final int MULTIPLIER_NEGATIVE_ONE = -1;
public static final String BALANCE_AFTER_MODIFICATION = "BalanceAfterModification";
public static final String COMMA = ",";
public static final String DOTPSV =".psv";
public static final String NEW_LINE = "\n";
}


 // Test Class
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class ConstantsTest {
private static File rootDir = new File(".");    
public static void main(String[] args) throws IOException {

    Map<String,Integer> accountBalance = new HashMap<String, Integer>();
    accountBalance.put("123",55000);
    accountBalance.put("223",15000);
    writeToFile(Constants.ACCOUNT, accountBalance, true, 2000);
    // do operation 

 }

/**
 * 
 * @param fileType
 * @param inputData
 * @param add if true add balance  else substract the balance 
 * @return
 * @throws IOException
 */
 private static File writeToFile(String fileType , Map<String,Integer>accountBalance ,boolean add, int amount) throws IOException{
     File file = null; 
     FileWriter fw = null;
     try{
         if(Constants.ACCOUNT.equals(fileType)){
             file = new File(rootDir,Constants.ACCOUNT+Constants.DOTPSV);//creating a fileName using constants
             fw = new FileWriter(file);
             fw.write(Constants.ACCOUNT+Constants.COMMA+Constants.BALANCE_AFTER_MODIFICATION);//Writing Header in file using constant values
             updateBalance(accountBalance, add, amount);
             for(String key:accountBalance.keySet()){
                 fw.write(Constants.NEW_LINE);
                 fw.write(key+Constants.COMMA+accountBalance.get(key));
             }
         }
         else if(Constants.EVENT_ITEM.equals(fileType))
         {
             // write to EventItem.psv
         }
     } finally{
         if (null!=fw){
             fw.close();
         }
     }

     System.out.println("File created successfully");
     return file;

 }

private static void updateBalance(Map<String, Integer> accountBalance,
        boolean add, int amount) {
    for(String key:accountBalance.keySet()){
         int currentBal = accountBalance.get(key);
         if(add){
             accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_ONE); // do lot of calculations
         }else{
             accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_NEGATIVE_ONE);// do a lot of calculations
         }
     }
}

}
公共最终类常量{
私有常量(){
}
公共静态最终字符串ACCOUNT=“ACCOUNT”;
公共静态最终字符串EVENT\u ITEM=“EventItem”;
公共静态最终整数乘数_ONE=1;
公共静态最终整数乘数\负\一=-1;
修改后的公共静态最终字符串余额=“BalanceAfterModification”;
公共静态最终字符串逗号=“,”;
公共静态最终字符串DOTPSV=“.psv”;
公共静态最终字符串NEW_LINE=“\n”;
}
//测试班
导入java.io.File;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
公共类常量测试{
私有静态文件rootDir=新文件(“.”);
公共静态void main(字符串[]args)引发IOException{
Map accountBalance=new HashMap();
账户余额。卖出价(“123”,55000);
账户余额。卖出价(“223”,15000);
writeToFile(Constants.ACCOUNT,accountBalance,true,2000);
//做手术
}
/**
* 
*@param文件类型
*@param inputData
*@param add if true add balance else减去余额
*@返回
*@抛出异常
*/
私有静态文件writeToFile(字符串文件类型、MapaccountBalance、布尔添加、整数金额)引发IOException{
File=null;
FileWriter fw=null;
试一试{
if(常量.ACCOUNT.equals(文件类型)){
file=新文件(rootDir,Constants.ACCOUNT+Constants.DOTPSV);//使用常量创建文件名
fw=新文件编写器(文件);
fw.write(Constants.ACCOUNT+Constants.COMMA+Constants.BALANCE\u修改后);//使用常量值在文件中写入头
更新平衡(账户余额、添加、金额);
for(字符串键:accountBalance.keySet()){
fw.write(常数新行);
write(key+Constants.逗号+accountBalance.get(key));
}
}
else if(常量.EVENT_ITEM.equals(文件类型))
{
//写入EventItem.psv
}
}最后{
如果(null!=fw){
fw.close();
}
}
System.out.println(“文件创建成功”);
返回文件;
}
私有静态无效更新平衡(映射accountBalance,
布尔加法(整数金额){
for(字符串键:accountBalance.keySet()){
int currentBal=accountBalance.get(键);
如果(添加){
accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER_ONE);//进行大量计算
}否则{
accountBalance.put(key,currentBal+amount*Constants.MULTIPLIER\u NEGATIVE\u ONE);//进行大量计算
}
}
}
}

请在我的示例中建议枚举更好,或者我当前使用常量的方法足够好

一个
枚举
没有为使用它的类定义一个
契约
,一个
接口
就可以了。使用枚举的类不是枚举的类型。实现接口的类实际上与接口的类型相同(接口是父级..,引用可以更改)。考虑到这些设计问题。告诉我,您的方法正确吗?

对于提供的示例,常量会更好。默认情况下,接口变量是公共静态final

public static final String ACCOUNT="Account";

请参见

您的枚举错误,您不应该创建枚举而不是常量:枚举是一组相关的常量,例如:

enum Days {
    SUNDAY, MONDAY, TUESDAY, ...
}
从:

枚举类型是一种特殊的数据类型,它使变量能够 一组预定义的常量


只有我们可以对单个组中的常量值使用枚举。 让我们假设:周、月、颜色、性别、过程状态

使用单个枚举存储所有常量不是一个好主意。相反,我们可以为每组常量使用一个枚举


让我们假设您维护了一些颜色代码,那么最好使用颜色枚举,而不是保存为常量

在您的特定情况下,使用枚举是经典的解决方案

首先,让我们将您的
常量重新编写为枚举:

public enum Constants {
    ACCOUNT,
    EVENT_ITEM,
    ;

}

public enum Operation {
   MULTIPLIER_ONE {
        public int action(int value) {
            return value;
        }
   },
   MULTIPLIER_NEGATIVE_ONE {
        public int action(int value) {
            return value * (-1);
        }
   },
   ;
   private Operation(int coef) {
        this.coef = coef;
   }

   public abstract int action(int value);
}
现在不写了:

if(Constants.ACCOUNT.equals(fileType)){
} else if(....)
您可以使用
switch/case
或更好的define:define方法(我们称之为
action()
进入枚举并从代码中调用它。请参见上面
操作
枚举中的示例。在这种情况下,您的代码变得很简单:不再使用
if/else
或switch语句。一切都很简单。验证在编译时完成:您在枚举中定义了抽象方法,如果不实现当使用由程序员负责维护的
if/else
结构时,这种情况不会发生

我只知道枚举的一个限制:在注释中使用字符串常量。有很多注释都带有字符串属性。例如
xmlement(name=“foo”)
。即使您定义了枚举

enum FooBar {
    foo, bar
}
您不能在批注中使用它:

@XmlElement(name=FooBar.foo) // is wrong because String type is required
@XmlElement(name=FooBar.foo.name()) // is wrong because annotations do not support method invocation 

在所有其他情况下,我更喜欢enum。

您应该在代码中使用enum

enum Constants {
  ACCOUNT,
  EVENT_ITEM ,
  COMMA ,
  DOTPSV ,
  BALANCE_AFTER_MODIFICATION ;

@Override
public String toString() {
  switch(this) {
    case ACCOUNT: return "Account";
    case EVENT_ITEM : return "EventItem";
    case COMMA : return ",";
    case DOTPSV : return ".psv";
    case BALANCE_AFTER_MODIFICATION : return "BalanceAfterModification";
    default: throw new IllegalArgumentException();
   }
 }
}

似乎是的副本,从设计角度看,您的代码与枚举相比具有完全不同的含义。@我展示了此代码,以让查看者知道我在不同的步骤中使用了用于不同目的的常量。此外,我还使用了定义常量的接口。因此,它们是默认公共静态final@TheLostMind对。编辑。我写这篇文章的时候没有看代码,所以我无法判断设计,但快速看一下会让我感到困惑…它隐含在接口定义中,但只是想提一下