枚举作为Java中常量的替换

问题描述 投票:1回答:6

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

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

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
         }
     }
}

}

请在我的示例示例中建议枚举会更好或者我目前使用常量的方法是否足够好?

java enums constants
6个回答
4
投票

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

首先,让我们重新编写你的Constants作为枚举:

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方法(让我们将它命名为action()进入枚举并从代码中调用它。请参阅上面Operation枚举中的示例。在这种情况下,您的代码变得微不足道:不再有if/else或switch语句。一切很简单。验证是在编译时完成的:你在enum中定义了抽象方法,你不能在没有为它实现这个方法的情况下为枚举添加另一个元素。当使用if/else结构维护时,这不会发生,这是程序员的责任。

我只知道枚举的一个限制:在注释中使用字符串常量。有许多带字符串属性的注释。例如qazxsw ppi。即使你定义枚举

XmlElement(name="foo")

你不能在注释中使用它:

enum FooBar {
    foo, bar
}

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


2
投票

您应该使用枚举此代码

@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 

0
投票

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(); } } } 没有为使用它的类定义Enumcontract确实如此。使用Enum的类不是Enum类型。实现接口的类实际上与接口类型相同(接口是父接口...并且可以更改引用)。考虑到这些设计问题。告诉我,你的方法是否正确?


0
投票

你得到枚举错误,它不像你应该创建枚举而不是常量:枚举是一组相关的常量,例如:

interface

来自enum Days { SUNDAY, MONDAY, TUESDAY, ... }

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


0
投票

对于提供的示例,常量将更好。默认情况下,接口变量是public static final。

docs

public static final String ACCOUNT="Account";


0
投票

只有我们可以将Enums用于单个组中的常量值。让我们假设:周,月,颜色,性别,过程状态

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

让我们假设您已经保留了一些颜色代码,然后更好地使用Color枚举而不是保存为常量。

© www.soinside.com 2019 - 2024. All rights reserved.