为什么要使用“final static int”?可以用作开关的大小写常量,但不能用作“final static

发布于 2024-10-07 11:47:32 字数 878 浏览 2 评论 0原文

为什么这个 int 开关有效:


public class Foo {
    private final static int ONE = 1;
    private final static int TWO = 2;

    public static void main(String[] args) {
        int value = 1;
        switch (value) {
            case ONE: break;
            case TWO: break;
        }
    }

}

虽然这个 enum 开关不是:


import java.lang.annotation.RetentionPolicy;

public class Foo {
    private final static RetentionPolicy RT = RetentionPolicy.RUNTIME;
    private final static RetentionPolicy SRC = RetentionPolicy.SOURCE;

    public static void main(String[] args) {
        RetentionPolicy value = RetentionPolicy.RUNTIME;
        switch (value) {
            case RT: break;
            case SRC: break;
        }
    }

}

我知道在这种情况下必须是一个常量,那么为什么我可以使用“final static int”作为常量而不是“final static” ;”?

Why is this int switch valid:


public class Foo {
    private final static int ONE = 1;
    private final static int TWO = 2;

    public static void main(String[] args) {
        int value = 1;
        switch (value) {
            case ONE: break;
            case TWO: break;
        }
    }

}

While this enum switch is not:


import java.lang.annotation.RetentionPolicy;

public class Foo {
    private final static RetentionPolicy RT = RetentionPolicy.RUNTIME;
    private final static RetentionPolicy SRC = RetentionPolicy.SOURCE;

    public static void main(String[] args) {
        RetentionPolicy value = RetentionPolicy.RUNTIME;
        switch (value) {
            case RT: break;
            case SRC: break;
        }
    }

}

I know that what goes in the case must be a constant, so why can I use a "final static int" as constant but not a "final static <your enum>"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深海蓝天 2024-10-14 11:47:32

因为 case 语句标签必须具有编译时常量或 EnumConstantName。 JLS 14.11

编译时间常数只能是字符串和原始类型,如

Because a case statement label must have either a compile time constant or an EnumConstantName. JLS 14.11

Compile time constants can only be strings and primitive types, as described by JLS 15.28. Thus you can not use a static final <your enum>, as it is neither a compile time constant, nor the name of an enum.

ぽ尐不点ル 2024-10-14 11:47:32

case 参数必须是原始的;它不能是一个对象。

但是,您可以按如下方式使用枚举:

RetentionPolicy value = ...
switch (value) {
    case RUNTIME:
    case SOURCE:
}

由于 value 被声明为 RetentionPolicy 类型,因此您可以直接在 switch 内部使用枚举常量。

The case argument must be primitive; it cannot be an object.

However, you can use enums as follows:

RetentionPolicy value = ...
switch (value) {
    case RUNTIME:
    case SOURCE:
}

Because value is declared to be of type RetentionPolicy you can use the enum constants directly inside the switch.

深海少女心 2024-10-14 11:47:32

或者简单地使用 if-elseif 情况:

private final static int ONE = 1;
private final static int TWO = 2;

public static void main(String[] args) {
    int value = 1;

    if(value.equals(ONE)){

    }
    else if(value.equals(ONE)){

    }

}

Or simply use a if-elseif case :

private final static int ONE = 1;
private final static int TWO = 2;

public static void main(String[] args) {
    int value = 1;

    if(value.equals(ONE)){

    }
    else if(value.equals(ONE)){

    }

}
风透绣罗衣 2024-10-14 11:47:32

编译器会说,

unqualified enumeration constant name required

因此您的 RT 值需要为 RUNTIME 而不是 RetentionPolicy.RUNTIME 才能使您的代码正常工作。但这当然是不可能的。为什么不直接使用 RetentionPolicy 枚举?如果您想坚持最终静态声明,则需要将整个枚举分配给最终静态变量。

The compiler says

unqualified enumeration constant name required

So your value of RT would need to be RUNTIME instead of RetentionPolicy.RUNTIME to make your code work. But of course that is not possible. Why not use the RetentionPolicy enum directly? If you want to stick to your final static declaration, you need to assign the whole enum to your final static variable.

囍孤女 2024-10-14 11:47:32

我有类似的要求,并通过打开枚举序数而不是打开枚举本身来解决这个问题。这不是很漂亮/直观,但它有效:

public class Foo {

    private final static int SRC = 0; // == RetentionPolicy.SOURCE.ordinal();
    private final static int RT = 2; // == RetentionPolicy.RUNTIME.ordinal();

    static{
        if (RT != RetentionPolicy.RUNTIME.ordinal() || SRC !=  RetentionPolicy.SOURCE.ordinal()) {
            throw new IllegalStateException("Incompatible RetentionPolicy.class file");
        }
    }

    public static void main(String[] args) {
        RetentionPolicy value = RetentionPolicy.RUNTIME;
        switch (value.ordinal()) {
            case RT: break;
            case SRC: break;
        }
    }

}

请注意,当然不可能将常量声明为例如,

private final static int SRC = RetentionPolicy.SOURCE.ordinal();

出于同样的原因,人们无法首先将常量声明为枚举......

I had a similar requirement and worked around this problem by switching on the Enums ordinal number instead of switching on the enum itself. This is not very beautiful/intuitive but it works:

public class Foo {

    private final static int SRC = 0; // == RetentionPolicy.SOURCE.ordinal();
    private final static int RT = 2; // == RetentionPolicy.RUNTIME.ordinal();

    static{
        if (RT != RetentionPolicy.RUNTIME.ordinal() || SRC !=  RetentionPolicy.SOURCE.ordinal()) {
            throw new IllegalStateException("Incompatible RetentionPolicy.class file");
        }
    }

    public static void main(String[] args) {
        RetentionPolicy value = RetentionPolicy.RUNTIME;
        switch (value.ordinal()) {
            case RT: break;
            case SRC: break;
        }
    }

}

Note that it is of course not possible to declare the constant as e.g.

private final static int SRC = RetentionPolicy.SOURCE.ordinal();

for the same reason one is not able to declare the constant as an Enum in the first place...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文