Java开关常量表达式...有没有任何聪明的方法来编译它?

时间:2011-08-01 22:03:59

标签: java

我离开它多年后才回到Java dev。无论如何都要编译这段代码吗?

class Mpeg4
    {
    public static final int FourCC2Int(char aA, char aB, char aC, char aD)
        {
        return (aA << 24) | (aB << 16) | (aC << 8) | (aD);
        }

    public static void main(String aArgs[]) throws Exception
        {
        int x = Integer.parseInt(aArgs[0]);

        switch (x)
            {
            case Mpeg4.FourCC2Int('f', 't', 'y', 'p'): // This won't be reduced by the compiler to a constant.
                // doSomething();
                break;

            }
        }
    }

我还尝试了一个类常量,例如

class Mpeg4
    {
    private static final int KFtyp = Mpeg4.FourCC2Int('f', 't', 'y', 'p');

    public static void main(String aArgs[]) throws Exception
        {
        int x = Integer.parseInt(aArgs[0]);

        switch (x)
            {
            case KFtyp: // Foiled again.
                // doSomething();
                break;
            }
        }
    }

语言已经发生了很大变化,我已经完成了谷歌搜索。有什么方法可以保持我的代码整洁 即不手动减少'宏'或具有潜在的大量if-then-else-if块? 也许编译器优化标志可能是一条路线?我觉得这种情况很蹩脚。

3 个答案:

答案 0 :(得分:4)

你可以这样做

    switch (x) {
    case ('f' << 24) | ('t' << 16) | ('y' << 8) | ('p'): 
        // doSomething();
        break;
    }

这是JLS关于什么可以进入常量表达式的部分案例。原来它非常灵活。

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#5313

答案 1 :(得分:3)

对于这些情况,

switch需要编译时常量表达式(来自Java 7的整数或枚举类型),并且方法调用的结果不是编译时常量。 (编译器不会调用您的方法。)

如果您只需要一个(或少数)个案例块,请改用if

如果你有一个很大的数字,你可以考虑使用HashMap或其他命令模式。或者让其他程序生成您的代码(例如,如果您正在编写解析器)。

答案 2 :(得分:2)

不 - 在编译时值必须是常量。 KFtyp在课程加载时保持不变。

在这方面,Java7对你有所帮助。 (交换机中允许进行字符串比较。)

但是,对单个变量进行一系列长检查的开关是最不实用的结构之一。总是,具有不同实现者的接口或具有子类的超类通过构造定义正确的行为是更好的选择。