Java - 带静态计数器的枚举

时间:2017-01-02 11:30:51

标签: java android enums jvm

我想在Java中实现类似枚举的C ++,所以我想使用静态字段作为计数器。这是我目前的解决方案:

library(shiny)

URLs <- c("http://www.google.com", "http://www.stackoverflow.com")

ui <- fluidPage(
  actionButton(
    "click",
    "Click here to open several browser tabs"
  )
)

server <- function(input, output){
  observeEvent(input$click, {
    for (i in URLs){
      browseURL(i)
      Sys.sleep(1)                #Short delay of 1 second
    }
  })
}

shinyApp(ui, server)

从上面的代码我应该得到: Test1.toInt() - &gt; 2,Test2.toInt() - &gt; 3,Test3.toInt() - &gt; 4,Test4.toInt() - &gt; 7,Test5.toInt() - &gt; 8

此代码适用于经过测试的Android Java VM,但我不确定它是否是有效的Java代码,是否能在所有有效的Java VM上正常运行,因为AFAIK枚举是在静态字段之前初始化,但是看起来像静态字段的嵌套类的初始化需要在这种情况下正常工作(没有嵌套类,简单的静态字段不起作用)。

祝你好运, Patryk

3 个答案:

答案 0 :(得分:0)

CounterHolder初始化之前,

ETest将始终被加载和初始化,因此您的代码应该在所有兼容的JVM上按预期工作。你可以在JLS中阅读更多关于类初始化的内容(不知道等效文档是针对android的,但我希望它们的措辞非常相似)。特别是:

  

类或接口类型T将在第一次出现以下任何一个之前立即初始化:

     
      
  • [...]
  •   
  • 使用T声明的静态字段,该字段不是常量变量。
  •   

所以最迟,CounterHolder类将在ETest的第一个构造函数运行之前加载并初始化。

但是请注意,从样式的角度来看,写下来可能更简洁:

enum ETest {
    Test1(2),
    Test2(3),
    Test3(4),
    Test4(7),
    Test5(8);
}

答案 1 :(得分:0)

实际上,您可以使用枚举内的Map轻松完成此操作

public enum TestEnum {
    Test1(2),
    Test2,
    Test3,
    Test4(7),
    Test5;

    private static Map<TestEnum, Integer> map = new HashMap<>();

    static {
        int counter = 0;
        for (TestEnum enun : TestEnum.values()) {

            counter = Math.max(counter, enun.value);
            if (enun.value == 0) {
                counter++;
            }
            map.put(enun, counter);
        }
    }

    private int value;

    TestEnum() {
        value = 0;
    }

    TestEnum(int pValue) {
        value = pValue;
    }

    public int toInt() {
        return map.get(this);
    }
}

这是打印结果的功能

for (TestEnum anEnum : TestEnum.values()) {
    System.out.println(anEnum.name() +" = "+ String.valueOf(anEnum.toInt()));
}

,输出为:

Test1 = 2
Test2 = 3
Test3 = 4
Test4 = 7
Test5 = 8
  

提示:检查名为ordinal的内容,它是枚举常量的序数(它在枚举声明中的位置,其中初始常量的序数为零) )。

答案 2 :(得分:0)

在android中,最好的做法是避免使用Enum,主要原因是反优化性能,基于android文档:

  

枚举通常需要的内存是静态内存的两倍多   常量。你应该严格避免在Android上使用枚举。

另一方面android目的解决方案类型def注释:

  

@IntDef注释让你基本上可以创建一个“typedef”,其中   您创建另一个表示有效整数的注释   您期望的常量,然后用此装饰您的API   typedef注释。

以下是一个示例示例,如何使用它(天数检查...): https://noobcoderblog.wordpress.com/2015/04/12/java-enum-and-android-intdefstringdef-annotation/

有关更多了解功能,您可以阅读官方文档: https://developer.android.com/studio/write/annotations.html#enum-annotations