Ordem de inicialização da variável estática
1. Regras simples
Primeiro, vejamos o código Java mais comum:
Public class Test {public static test1 t = new test1 (); public static int a = 0; public static int b; public static void main (string [] arg) {System.out.println (test.a); System.out.println (test.b); }} classe test1 {public test1 () {test.a ++; Test.b ++; }}Aqui está um palpite qual é o resultado da saída do console?
Ok, talvez você tenha adivinhado o resultado abaixo, então ainda está familiarizado com o Java.
Copie o código da seguinte forma: 0 1
Se você não entende por que o resultado acima é emitido, então eu vou lhe dizer.
A inicialização da variável estática Java segue as seguintes regras:
Depois de ler isso, você entenderá que o valor do teste. A mudou três vezes.
Definido como 0 quando declarado >> test1 :: test1 está definido como 1 >> test.a é inicializado como 0
2. Regras complexas
Se você entender isso, observe o código abaixo.
public classe A {public static int b = ba; public static a plus = novo a ("a"); public static final int finalint = (int) (math.random ()*100); public static b p = new B ("A"); public static final string finalalstr = "finalalstr"; Public Static Final Integer FinalInteger = New Integer (10); public static int a = 1; public static b c = nulo; public a (string de) {System.out.println ("----------- Begin a :: a ----------------"); System.out.println ("a :: a, de ="+de); System.out.println ("A :: a, ab ="+ab); System.out.println ("A :: a, A.FinalInt ="+A.Finalint); System.out.println ("a :: a, ba ="+ba); System.out.println ("A :: a, B.Plus ="+B.Plus); System.out.println ("----------- END A :: A ----------------"); } public static void main (string [] arg) {System.out.println ("main, ab ="+ab); System.out.println ("main, bt ="+bt); System.out.println ("main, ca ="+ca); }} classe b {public static int t = aa; public static a plus = novo a ("b"); public static int a = 1; public b (string de) {System.out.println ("----------- Comece b :: b -----------------------"); System.out.println ("b :: b, de ="+de); System.out.println ("b :: b, ba ="+ba); System.out.println ("b :: b, aa ="+aa); System.out.println ("B :: B, Ap ="+AP); System.out.println ("B :: B, A.Plus ="+A.Plus); System.out.println ("B :: B, A.Finalint ="+A.Finalint); System.out.println ("B :: B, A.Finalint ="+A.Finalint); System.out.println ("B :: B, A.Finalint ="+A.Finalint); System.out.println ("B :: B, A.Finalint ="+A.Finalint); System.out.println ("B :: B, A.FinalInteger ="+A.FinalInteger); System.out.println ("B :: B, A.Finalaltr ="+A.FinalalStr); System.out.println ("----------- END B :: B ----------------"); }} classe C {public static final a a = novo a ("c");}Você ainda consegue adivinhar o resultado da saída? Eu escrevi durante o teste, então não achei. Haha
O resultado da saída do console é:
----------- Comece a :: a ---------------- a :: a, de = ba :: a, ab = 0a :: a, a.finalInt = 0a :: a, ba = 0a :: a, b.plus = null ----------- END A :: A ----------------- A.FinalInt = 0a :: a, ba = 1a :: a, b.plus=a@a90653---------- END A :: a ----------------------------- Comece b :: b ---------------- b :: b, de = ab :: b, ba = 1b: b, aa = 0b :: b, Ap = null B: A.FinalInt = 61b :: b, a.FinalInteger = nullb :: b, A.FinalStr = Finalstr ----------- End B :: B ---------------- MAIN, AB = 1Main, Bt = 0 --------- Begin A :: A ------------- a: a: a, de = Ca: A, AB = 1A. B.plus=a@a90653---------- END A :: A -------------------- MAIN, CA = A@61DE33
Você não achou esse resultado, haha.
Leva muito tempo para explicar os resultados da execução do programa um por um. Aqui, escreveremos diretamente as regras seguidas pela inicialização da variável estática Java.
As regras no primeiro parágrafo ainda são válidas, mas não são sólidas.
Inicialização de dados estáticos
Adicionar campos qualificados estático é o chamado campo de classe, o que significa que o proprietário desse campo não é um objeto, mas uma classe. Não importa quantos objetos sejam criados, existe apenas uma cópia dos dados estáticos.
O campo estático é sempre inicializado na classe e, em seguida, o campo geral é inicializado. Em seguida, inicialize o construtor. No entanto, se um objeto dessa classe não for criado, o objeto não será inicializado e será executado apenas uma vez.
Como no código a seguir, na classe Staticinitialization, tabela estática tabela = new tabela (); Primeiro, e depois o objeto da tabela não será inicializado, caso contrário, ele não será inicializado.
Classe Bowl {Bowl (int Marker) {print ("Bowl (" + Marker + ")"); } void f1 (int marker) {print ("f1 (" + marker + ")"); }} tabela de classe {tigela estática 1 = nova tigela (1); Tabela () {print ("tabela ()"); Bowl2.f1 (1); } void f2 (int marker) {print ("f2 (" + marker + ")"); } tigela estática tigela2 = nova tigela (2);} armário de classe {tigela de tigela 3 = nova tigela (3); tigela estática tigela4 = nova tigela (4); Cupboard () {print ("cupboard ()"); Bowl4.f1 (2); } void f3 (int marker) {print ("f3 (" + marker + ")"); } tigela estática tigela5 = nova tigela (5);} classe pública staticinitialization {public static void main (string [] args) {print ("criando novo cupboard () em main"); novo armário (); print ("Criando novo armário () em Main"); novo armário (); tabela.f2 (1); cupboard.f3 (1); } tabela estática tabela = new tabela (); armário estático armário = novo armário ();}Saída:
Tigela (1) tigela (2) tabela () f1 (1) tigela (4) tigela (5) tigela (3) armário () f1 (2) criando um novo armário () no armário principal (3) armário () f1 (2) criando um novo armário () em maingowl (3) cupboard () f1 (2) f2 (1) f3 (1)
A inicialização estática exibida (ou seja, blocos estáticos)
Colocar várias declarações de inicialização em uma cinta estática é chamado de bloco estático. De fato, está escrito em conjunto escrevendo várias estáticas, e a essência é a mesma. Executa apenas quando o objeto é criado pela primeira vez ou o campo da classe é acessado pela primeira vez e apenas uma vez.
classe Cup {Cup (int marker) {print ("Cup (" + Marker + ")"); } void f (int marker) {print ("f (" + marker + ")"); }} copos de classe {xícara estática de copo1; Copa estática de copo2; estático {cup1 = novo copo (1); cop2 = novo copo (2); } Cops () {print ("cups ()"); }} classe pública explicitstatic {public static void main (string [] args) {print ("interno main ()"); Cops.cup1.f (99); // (1)} // copos estáticos copos1 = novos copos (); // (2) // xícaras estáticas copos2 = novos copos (); // (2)}Saída:
Inside Main () Cup (1) Cup (2) F (99)
Inicialização de instância não estática
Não há nada a dizer sobre isso, é apenas uma inicialização comum, executada em ordem e pode ser executada várias vezes.
classe caneca {caneca (int marker) {print ("caneca (" + marker + ")"); } void f (int marker) {print ("f (" + marker + ")"); }} classe pública canecas {caneca caneca; MUG MUG2; {MUG1 = nova caneca (1); Mug2 = nova caneca (2); impressão ("Mug1 e Mug2 inicializado"); } Caves () {print ("caves ()"); } Canecas (int i) {print ("canecas (int)"); } public static void main (string [] args) {print ("Inside main ()"); novas canecas (); print ("novas canecas () concluídas"); novas canecas (1); impressão ("novas canecas (1) concluídas"); }}Inside Main () Caneca (1) Caneca (2) MUG1 e MUG2 InitializedMugs () New Canelas () Concluído (1) Caneca (2) MUG1 e MUG2 Inicializados (int) Novas canecas (1) concluídas