Java 具有非常量情况的Switch语句

Java 具有非常量情况的Switch语句,java,command-line,internationalization,switch-statement,Java,Command Line,Internationalization,Switch Statement,我正在处理这个任务,在这个任务中我使用命令行界面。我使用一个简单的switch语句来创建这个命令行界面的控件,但是当我添加国际化支持作为我任务的一部分时,我的switch语句已经中断,因为其中的变量需要是常量。我该怎么做 public class Editor { private boolean running = true; public static ArrayList<String> command = new ArrayList<String>

我正在处理这个任务,在这个任务中我使用命令行界面。我使用一个简单的switch语句来创建这个命令行界面的控件,但是当我添加国际化支持作为我任务的一部分时,我的switch语句已经中断,因为其中的变量需要是常量。我该怎么做

public class Editor {

    private boolean running = true;

    public static ArrayList<String> command = new ArrayList<String>();

    Locale enLocale = new Locale("en", "GB");
    ResourceBundle messages = ResourceBundle.getBundle("BaseBundle", enLocale);
    String open = messages.getString("open");
    String saveas = messages.getString("saveas");
    String put = messages.getString("put");
    String rot90 = messages.getString("rot90");
    String mono = messages.getString("mono");
    String help = messages.getString("help");
    String quit = messages.getString("quit");
    String look = messages.getString("look");
    String undo = messages.getString("undo");
    private String get = messages.getString("get");

    Parser parser = new Parser();

    public Editor() {
    }

    public void run() {
        System.out.println("fotoshop");
        while (running) {
            command = parser.readInput();
            interpret(command);
        }
        System.out.println("fotoshop exiting");
    }

    public void interpret(ArrayList<String> command) {


        switch (command.get(0)) {
            case open: OpenCommand.execute();
            case saveas: SaveCommand.execute();
            case put: PutCommand.execute();
            case get: GetCommand.execute();
            case rot90: ApplyRot90.execute();
            case mono: ApplyMono.execute();
            case help: HelpCommand.execute();
            case quit: running = false;
            case look: LookCommand.execute();
            case undo;

        }
    }



}
公共类编辑器{
私有布尔运行=真;
public static ArrayList命令=new ArrayList();
Locale enLocale=新的语言环境(“en”、“GB”);
ResourceBundle messages=ResourceBundle.getBundle(“BaseBundle”,enLocale);
字符串打开=messages.getString(“打开”);
String saveas=messages.getString(“saveas”);
String put=messages.getString(“put”);
String rot90=messages.getString(“rot90”);
String mono=messages.getString(“mono”);
字符串帮助=messages.getString(“帮助”);
String quit=messages.getString(“quit”);
String look=messages.getString(“look”);
String undo=messages.getString(“undo”);
私有字符串get=messages.getString(“get”);
Parser Parser=新解析器();
公共编辑(){
}
公开募捐{
System.out.println(“fotoshop”);
(跑步时){
command=parser.readInput();
翻译(命令);
}
System.out.println(“fotoshop退出”);
}
公共void解释(ArrayList命令){
开关(command.get(0)){
case open:OpenCommand.execute();
case saveas:SaveCommand.execute();
case put:PutCommand.execute();
case get:GetCommand.execute();
case rot90:ApplyRot90.execute();
case mono:ApplyMono.execute();
案例帮助:HelpCommand.execute();
案例退出:running=false;
case-look:LookCommand.execute();
案例撤销;
}
}
}

您是否看过以下实现动态切换的技巧? 这可能有点过分,但值得一看

您可以使用字符串而不是整数来定义它,以将其映射到应用程序应支持的不同语言中的不同操作

甚至更好地避免将所有消息直接硬编码到hashmap中,从而在添加新的语言支持时不得不重新编译更改代码

将示例程序国际化

如果您查看国际化的源代码,您会注意到 硬编码的英文邮件已被删除。因为这些信息 不再硬编码,因为语言代码在 运行时,相同的可执行文件可以在全球范围内分发。不 本地化需要重新编译。这项计划已经完成 国际化

您可能想知道消息的文本发生了什么,或者是什么 语言和国家代码意味着什么。别担心。你会了解 这些概念是在您逐步实现国际化的过程中提出的 示例程序

1。创建属性文件

属性文件存储有关对象特征的信息 程序或环境。属性文件为纯文本格式。你 可以使用几乎任何文本编辑器创建文件

在本例中,属性文件存储 要显示的消息。在项目国际化之前, 本文本的英文版本在
System.out.println
语句。默认属性文件,即 名为MessagesBundle.properties,包含以下行:

问候语=你好
再见=再见
inquiry=你好吗?
现在 消息位于属性文件中,可以将其转换为 各种语言。不需要对源代码进行任何更改。这个 French translator创建了一个名为
MessagesBundle\u fr\u fr.properties
,其中包含以下行:

问候语=你好。 告别=再见。
inquiry=Comment
你好吗?请注意,这些值位于等号的右侧 已翻译,但左侧的键尚未翻译 改变。这些键不能更改,因为它们将被引用 当程序获取翻译文本时

属性文件的名称很重要。例如,的名称
MessagesBundle\u fr\u fr.properties
文件包含fr语言代码 以及《联邦共和国国家代码》。这些代码也用于创建 区域设置对象

2。定义区域设置

String com = command.get(0);
if (com.equals(open)) {
    OpenCommand.execute()
} else if (com.equals(saveas)) {
    SaveCommand.execute();
} ...
Locale对象标识特定的语言和国家。这个 下面的语句定义语言为英语的区域设置 这个国家是美国:

aLocale=新的语言环境(“en”、“US”)下一个示例创建区域设置
加拿大和法国的法语对象:

caLocale=新区域设置(“fr”、“CA”)
frLocale=新语言环境(“fr”、“fr”)
该程序非常灵活。不使用硬编码语言和
国家代码,程序在运行时从命令行获取
时间:

String language=新字符串(args[0])
String country=新字符串(args[1])
currentLocale=新的语言环境(语言、国家)区域设置
对象只是标识符。定义区域设置后,将其传递给
执行有用任务的其他对象,例如格式化日期和
数字。这些对象对区域设置敏感,因为它们的行为
根据地点的不同而不同。ResourceBundle是
区域设置敏感对象

3。创建一个ResourceBundle

String com = command.get(0);
if (com.equals(open)) {
    OpenCommand.execute()
} else if (com.equals(saveas)) {
    SaveCommand.execute();
} ...
资源包
Command on {id: 1}
Command on {id: 2}
Command on {id: 3}
Command on {default}
Map<String, String> i18Map = new HashMap<>();
map.put("open", "open");    // English
map.put("abierto", "open"); // Spanish
map.put("ouvrir", "open");  // French
// other words/languages
String input = parser.readInput();
String command = i18Map.get(input);

switch (command.get(0)) {
    case "open": OpenCommand.execute();
    case "saveas": SaveCommand.execute();
    case "put": PutCommand.execute();
    case "get": GetCommand.execute();
    // etc.
}
String com = command.get(0);
if (com.equals(open)) {
    OpenCommand.execute()
} else if (com.equals(saveas)) {
    SaveCommand.execute();
} ...
Map<String,Command> commandsByInternationalisedString = new HashMap<String,Command>();
Locale enLocale = new Locale("en", "GB");
ResourceBundle messages = ResourceBundle.getBundle("BaseBundle", enLocale);

commandsByInternationalisedString.add(messages.getString("open"), new OpenCommand());
commandsByInternationalisedString.add(messages.getString("saveas"), new SaveAsCommand());
commandsByInternationalisedString.add(messages.getString("put"), new PutCommand());
public void interpret(ArrayList<String> command) {

    Command toExecute = commandsByInternationalisedString.get(command.get(0));
    if (toExecute != null ) {
        toExecute.execute();
    } else {
        System.out.println("That's not a valid command");
    }
}