característica interessante com campos estáticos. exceção StackOverflow

votos
2

Você tem alguma ideia, por isso que o seguinte código:

public class A
{
    public static int i = B.i + 1;
}

public class B 
{
    public static int i = A.i + 1;
}

Tendo:

        int aa = A.i;
        int bb = B.i;

Diz que aa = 2 (!!!) e bb = 1.

Eu tenho um estouro de pilha em meu cérebro !!! Tanto quanto eu entendo, recursão pára em métodos estáticos, mas por quê? Se você refazer int i para os getters (para depurar e entender por que diabos ele funciona assim), você recebe a exceção de estouro de pilha.

Publicado 19/05/2009 em 16:58
fonte usuário
Em outras línguas...                            


3 respostas

votos
6

Sem dúvida execução está acontecendo assim:

O B.iinicializador estático é executado primeiro, e conjuntos B.i = A.i + 1. Desde A.iainda não foi inicializado, A.ié igual default(int), o que é 0. B.iobtém o valor 1.

O A.iinicializador estático é executado em segundo, e conjuntos A.i = B.i + 1 = 2.

Desde inicializadores estáticos executado em uma ordem definida, você pode achar que um campo diferente é 2cada vez que você executá-lo, ou que mudar quando você faz outras mudanças estruturais em seu código. No entanto, deve-se sempre acabam como 2, e deve-se sempre 1.

PS Isto não tem nada a ver com o polimorfismo.

EDIT: Para alguns maior compreensão do momento do inicializadores estáticos e construtores, você pode querer examinar esta parte relevante da especificação C #.

Respondeu 19/05/2009 em 17:03
fonte usuário

votos
4

Um campo não é como um getter propriedade. Ele apenas armazena os dados, não qualquer operação. Na verdade, a inicialização irá ser transferida para um outro método (construtor estático, .cctor) que irá inicializar variáveis estáticas na classe.

No início, ambos será igual a 0. Antes de acessar A.ipela primeira vez, o método .cctorpara a classe Aé executado. Ele tenta acessar B.ipela primeira vez que fará com que a execução do construtor estático da classe B. .cctorde Btentar acessar A.i, mas desde que não é a primeira vez que um campo está sendo acessado, construtor estático de Avai não correr mais. Ele só obtém o valor atual de Aque ainda é 0. Consequentemente, B.iserá igual a 1 quando B..cctora execução acabamentos e controle é retornado para A..cctor. Ele vai ver o valor B.ie adiciona 1 a ela e as armazena em A.i. Assim, A.ivai ser igual a 2 (1 + 1) eB.i vai ser igual a 1.

A única garantia que você tem é que o construtor estático será chamado antes de qualquer membro estático dessa classe é acessada.

Respondeu 19/05/2009 em 17:02
fonte usuário

votos
1

Aqui está o que está acontecendo.

  • Um é acessada pela primeira vez.
  • Ai é criado com o valor 0.
  • O inicializador estático para uma roda.
  • B é acessada pela primeira vez.
  • Ai é acessado. Atualmente tem valor 0.
  • Bi é definido como 1. Ai é definido como 2.

A coisa realmente importante a notar é que as propriedades estáticas estão sendo inicializado para seus padrões e , em seguida, o inicializador estático é executado.

Pessoalmente, eu evitar inicialização estática, estado estático eo resto, tanto quanto possível. Há muitas armadilhas.

Respondeu 19/05/2009 em 18:37
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more