Por que não posso ter "const const static S =" stuff "; na minha classe?

321

Ao tentar compilar minha classe, recebo um erro:

A constante 'NamespaceName.ClassName.CONST_NAME'não pode ser marcada como estática.

na linha:

public static const string CONST_NAME = "blah";

Eu poderia fazer isso o tempo todo em Java. O que estou fazendo de errado? E por que não me deixa fazer isso?

jjnguy
fonte

Respostas:

583

Um constobjeto é sempre static.

Joel Coehoorn
fonte
2
const torna a variável constante e não pode ser alterada.
Samuel
6
@ jinguy: const significa inerentemente estático - se você tem algum const, ele já está estático, e estático, portanto, não precisa ser nem pode ser especificado.
John Rudy
8
@jjnguy: Por quê? readonly é realmente mais flexível que o final de Java para variáveis ​​- você pode configurá-lo quantas vezes quiser no construtor, mas não em outro lugar. Isso pode ser muito útil.
Jon Skeet
67
As consts são alinhadas no tempo de compilação e não estão presentes no objeto de tipo estático no tempo de execução. As estáticas não são incorporadas e vivem dentro do objeto de texto. Acrescento isto apenas porque ninguém mencionou a diferença ...
3
Eles ainda estão presentes no tempo de execução - você pode vê-los com reflexão, por exemplo (com GetField).
Jon Skeet
32

Um membro const é considerado estático pelo compilador, além de implicar em semântica de valor constante, o que significa que as referências à constante podem ser compiladas no código de uso como valor do membro constante, em vez de uma referência ao membro.

Em outras palavras, um membro const que contém o valor 10 pode ser compilado no código que o usa como o número 10, em vez de uma referência ao membro const.

Isso é diferente de um campo estático somente leitura, que sempre será compilado como uma referência ao campo.

Observe que isso é pré-JIT. Quando o JIT'ter entra em ação, ele pode compilar esses dois no código de destino como valores.

Lasse V. Karlsen
fonte
Ponto muito importante, que o código compilado presume que o valor constante não será alterado em uma versão futura.
PJTraill
6

C # consté exatamente a mesma coisa que Java final, exceto que é absolutamente sempre static. Na minha opinião, não é realmente necessário que uma constvariável seja não static, mas se você precisar acessar uma constvariável não- staticé, você pode:

class MyClass
{    
    private const int myLowercase_Private_Const_Int = 0;
    public const int MyUppercase_Public_Const_Int = 0;

    /*        
      You can have the `private const int` lowercase 
      and the `public int` Uppercase:
    */
    public int MyLowercase_Private_Const_Int
    {
        get
        {
            return MyClass.myLowercase_Private_Const_Int;
        }
    }  

    /*
      Or you can have the `public const int` uppercase 
      and the `public int` slighly altered
      (i.e. an underscore preceding the name):
    */
    public int _MyUppercase_Public_Const_Int
    {
        get
        {
            return MyClass.MyUppercase_Public_Const_Int;
        }
    } 

    /*
      Or you can have the `public const int` uppercase 
      and get the `public int` with a 'Get' method:
    */
    public int Get_MyUppercase_Public_Const_Int()
    {
        return MyClass.MyUppercase_Public_Const_Int;
    }    
}

Bem, agora percebo que essa pergunta foi feita há 4 anos, mas desde que dediquei cerca de 2 horas de trabalho, consistindo em tentar todos os tipos de maneiras diferentes de responder e formatar o código, nesta resposta, ainda estou postando. :)

Mas, para constar, ainda me sinto meio bobo.

Meowmaritus
fonte
4
Até onde eu sei, o Java finalse comporta exatamente como C # readonly, e nem constum pouco.
Ben Voigt
@jjnguy Obrigado pela edição; Realmente não sei por que escolhi esse texto original.
Meowmaritus
6

Do MSDN: http://msdn.microsoft.com/en-us/library/acdd6hb7.aspx

... Além disso, enquanto um campo const é uma constante em tempo de compilação , o campo somente leitura pode ser usado para constantes de tempo de execução ...

Portanto, usar estática em campos const é como tentar tornar uma estática definida (com #define) em C / C ++ ... Como é substituída por seu valor no tempo de compilação, é claro que é iniciada uma vez para todas as instâncias (= estática) .

uriel
fonte
2

const é semelhante ao estático, podemos acessar as duas variáveis ​​com o nome da classe, mas diff é que as variáveis ​​estáticas podem ser modificadas e o const não.

soujanya
fonte