Então, eu estou trabalhando nessa classe que tem algumas constantes estáticas:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Então, eu gostaria de uma maneira de obter uma string relevante com base na constante:
public static String lookup(int constant) {
switch (constant) {
case Foo.BAR: return "bar";
case Foo.BAZ: return "baz";
case Foo.BAM: return "bam";
default: return "unknown";
}
}
No entanto, ao compilar, recebo um constant expression required
erro em cada um dos três rótulos de casos.
Entendo que o compilador precisa que a expressão seja conhecida no momento da compilação para compilar um comutador, mas por que não é Foo.BA_
constante?
java
compile-time-constant
Austin Hyde
fonte
fonte
public static final int
s estão espalhados por todo o JDK, então foi com isso que eu fui.Respostas:
Embora sejam constantes da perspectiva de qualquer código que seja executado após a inicialização dos campos, eles não são uma constante de tempo de compilação no sentido exigido pelo JLS; consulte §15.28 Expressões constantes para a especificação de uma expressão constante 1 . Isso se refere a §4.12.4 Variáveis finais, que define uma "variável constante" da seguinte maneira:
No seu exemplo, as variáveis Foo.BA * não possuem inicializadores e, portanto, não se qualificam como "variáveis constantes". A correção é simples; altere as declarações da variável Foo.BA * para ter inicializadores que são expressões constantes em tempo de compilação.
Em outros exemplos (onde os inicializadores já são expressões constantes em tempo de compilação), declarar a variável como
final
pode ser o necessário.Você pode alterar seu código para usar um
enum
int
constantes em vez de constantes, mas isso traz outras restrições diferentes:default
caso, mesmo se tivercase
para cada valor conhecido doenum
; Vejo Por que o padrão é necessário para uma troca em uma enumeração?case
rótulos devem ser todosenum
valores explícitos , não expressões que são avaliadas comoenum
valores.1 - As restrições de expressão constante podem ser resumidas da seguinte forma. Expressões constantes a) pode utilizar os tipos de primitivas e
String
única, b) permitir que primárias que são literais (apartenull
) e variáveis constantes única, c) permitir que expressões constantes possivelmente parenthesised como subexpress~oes, d) permitir que os operadores excepto para operadores de atribuição,++
,--
ouinstanceof
, e e) permitir a conversão de tipos para tipos primitivos ouString
apenas.Note que isto não inclui qualquer forma de método ou lambda chamadas,
new
,.class
..length
ou assinatura de matriz. Além disso, qualquer uso de valores de matriz,enum
valores, valores de tipos de invólucros primitivos, boxe e unboxing são todos excluídos por causa de a).fonte
Você obtém a expressão Constant necessária porque deixou os valores fora de suas constantes. Experimentar:
fonte
Eu recebi esse erro no Android e minha solução foi apenas usar:
ao invés de
fonte
Porque essas não são constantes de tempo de compilação. Considere o seguinte código válido:
Você só pode saber o valor de
BAR
em tempo de execução.fonte
public static final int BAR = new Random().nextInt()
?new Random().nextInt()
retornar os mesmos valores?Você pode usar uma enumeração como neste exemplo:
Fonte: instrução Switch com enum
fonte
enum Codes { CODE_A(1), CODE_B(2); private mCode; Codes(int i) { mCode = i; } public int code() { return mCode; } }
<br/> Quando tento usar a enum no comutador, recebo o mesmo erro ... <br/>switch(field) { case Codes.CODE_A.code() : // do stuffs.. ; }
<br/> É possível resolver o problema?Isso foi respondido há séculos e provavelmente não é relevante, mas apenas por precaução. Quando fui confrontado com esse problema, simplesmente usei uma
if
declaração em vez deswitch
resolver o erro. É claro que é uma solução alternativa e provavelmente não é a solução "certa", mas, no meu caso, foi apenas o suficiente.fonte
switch
geralmente é mais rápido do que longoif-else
, porqueswitch
apenas verifique a condição uma vez , enquantoif-else
você pode precisar verificar todas as condições antes de encontrar a correta.Às vezes, a variável switch também pode cometer esse erro, por exemplo:
Para resolver, você deve converter a variável em int (neste caso). Assim:
fonte
Este erro ocorreu no Android ao fazer algo assim:
apesar de declarar uma constante:
public static final String ADMIN_CONSTANT= "Admin";
Resolvi o problema alterando meu código para este:
fonte
No meu caso, eu estava recebendo essa exceção porque
no segundo caso, eu estava chamando a constante da instância,
var.MODIFICAR_KM:
mas deveria usarVariablesKmDialog.OBTENER_KM
diretamente da classe.fonte
Se você o estiver usando em um caso de comutador, precisará obter o tipo de enum antes mesmo de conectar esse valor ao comutador. Por exemplo :
E o enum é como:
fonte
O código abaixo é auto-explicativo. Podemos usar uma enumeração com uma caixa de opção:
Com base nos valores de classe da enumeração, podem ser mapeados:
Espero que ajude :)
fonte
Eu recomendo usar da seguinte maneira:
fonte
private Animal(String name) { this.name = name; }
Eu recomendo que você use enums :)
Veja isso:
Então você pode usá-lo assim:
fonte