Qual é a diferença entre a inicialização dentro de um static
bloco:
public class staticTest {
static String s;
static int n;
static double d;
static {
s = "I'm static";
n = 500;
d = 4000.0001;
}
...
E inicialização estática individual:
public class staticTest {
static String s = "I'm static";
static int n = 500;
static double d = 4000.0001;
....
java
static-initialization
Adam Matan
fonte
fonte
Respostas:
Um bloco de inicialização estático permite uma inicialização mais complexa, por exemplo, usando condicionais:
static double a; static { if (SomeCondition) { a = 0; } else { a = 1; } }
Ou quando mais do que apenas construção é necessária: ao usar um construtor para criar sua instância, o tratamento de exceções ou trabalho diferente de criar campos estáticos é necessário.
Um bloco de inicialização estática também é executado após os inicializadores estáticos in-line, portanto, o seguinte é válido:
static double a; static double b = 1; static { a = b * 4; // Evaluates to 4 }
fonte
Um uso típico:
private final static Set<String> SET = new HashSet<String>(); static { SET.add("value1"); SET.add("value2"); SET.add("value3"); }
Como você faria isso sem o inicializador estático?
fonte
SET
e use a variável initializer (private final static Set<String> SET = createValueSet()
). E se você tivesse 5 conjuntos e 2 mapas, você simplesmente despejaria todos eles em um únicostatic
bloco?Você pode usar o bloco try / catch dentro
static{}
como abaixo:MyCode{ static Scanner input = new Scanner(System.in); static boolean flag = true; static int B = input.nextInt(); static int H = input.nextInt(); static{ try{ if(B <= 0 || H <= 0){ flag = false; throw new Exception("Breadth and height must be positive"); } }catch(Exception e){ System.out.println(e); } } }
PS: Referido a partir disso !
fonte
O tratamento de exceções durante a inicialização é outro motivo. Por exemplo:
static URL url; static { try { url = new URL("https://blahblah.com"); } catch (MalformedURLException mue) { //log exception or handle otherwise } }
Isso é útil para construtores que irritantemente lançam exceções verificadas, como acima, ou então uma lógica de inicialização mais complexa que pode ser sujeita a exceções.
fonte
Às vezes, você deseja fazer mais do que apenas atribuir valores a variáveis estáticas. Visto que você não pode colocar instruções arbitrárias no corpo da classe, você poderia usar um bloco inicializador estático.
fonte
No seu exemplo, não há diferença; mas muitas vezes o valor inicial é mais complexo do que confortavelmente expresso em uma única expressão (por exemplo, é um
List<String>
cujo conteúdo é melhor expresso por umfor
-loop; ou é umMethod
que pode não existir, portanto, manipuladores de exceção são necessários) e / ou os campos estáticos precisam ser definidos em uma ordem específica.fonte
static
bloco pode ser usado para inicializar a instância singleton , para evitar o uso do método sincronizadogetInstance()
.fonte
Tecnicamente, você poderia escapar sem ele. Alguns preferem que o código de inicialização de várias linhas entre em um método estático. Estou muito feliz em usar um inicializador estático para uma inicialização de várias instruções relativamente simples.
Claro, eu quase sempre faria minha estática
final
e apontaria para um objeto não modificável.fonte
A palavra-chave estática (seja uma variável ou bloco) pertence à classe. Portanto, quando a classe é chamada, essas variáveis ou blocos são executados. Portanto, a maior parte da inicialização será feita com a ajuda da palavra-chave estática. Por pertencer à própria classe, a classe pode acessá-la diretamente, sem criar uma instância da classe.
Exemplo:
class Shoe { int size; String colour; static String brand = "Nike"; public Shoe(int size, String colour) { super(); this.size = size; this.colour = colour; } void displayShoe() { System.out.printf("%-2d %-8s %s %n",size,colour, brand); } public static void main(String args[]) { Shoe s1 = new Shoe(7, "Blue"); Shoe s2 = new Shoe(8, "White"); System.out.println("================="); s1.displayShoe(); s2.displayShoe(); System.out.println("================="); } }
fonte
O bloco de código estático permite inicializar os campos com mais de uma instrução, inicializar os campos em uma ordem diferente das declarações e também pode ser usado para a inicialização condicional.
Mais especificamente,
static final String ab = a+b; static final String a = "Hello,"; static final String b = ", world";
não funcionará porque aeb são declarados após ab.
No entanto, eu poderia usar um init estático. bloco para superar isso.
static final String ab; static final String a; static final String b; static { b = ", world"; a = "Hello"; ab = a + b; } static final String ab; static final String a; static final String b; static { b = (...) ? ", world" : ", universe"; a = "Hello"; ab = a + b; }
fonte
ab
declaração abaixo da declaração deb
.Usamos construtores para inicializar nossas variáveis de instância (variáveis não estáticas, variáveis que pertencem a objetos, não a classe).
Se você deseja inicializar variáveis de classe (variáveis estáticas) e deseja fazê-lo sem criar um objeto (construtores só podem ser chamados ao criar um objeto), então você precisa de blocos estáticos.
static Scanner input = new Scanner(System.in); static int widht; static int height; static { widht = input.nextInt(); input.nextLine(); height = input.nextInt(); input.close(); if ((widht < 0) || (height < 0)) { System.out.println("java.lang.Exception: Width and height must be positive"); } else { System.out.println("widht * height = " + widht * height); } }
fonte
System.out.println("B * H");
é bastante inútil. E a resposta em si é muito vaga. OP não mencionou construtores ou variáveis de instância.Um bloco de inicialização estático é útil se você deseja inicializar os tipos estáticos de classe especificados, antes do primeiro uso da classe. O uso subsequente não invocará nenhum bloco de inicialização estático. É o oposto direto de inicializadores de instância, que inicializam membros de instância.
fonte
Quando você quiser avaliar qualquer expressão durante o tempo de carregamento da classe, você pode usar o bloco estático, mas lembre-se:
fonte