简体   繁体   English

Java静态字段用法

[英]Java static field usage

I applied a job and they gave me a java test. 我申请了一份工作,他们给了我一个java测试。 There were many unknown concepts that I'm not familiar with, and have newer seen as well. 有许多我不熟悉的未知概念,也有较新的概念。 One is about static field. 一个是静态场。 I'm posting one of the strangest question below and asking for help. 我发布了下面最奇怪的问题之一并寻求帮助。

The code includes the question in comments. 代码包含注释中的问题。

public class MyClass {

    //what is the purpose of section, I mean for which purpose is it being used?
    //can variables inside of belove section be used or not. If can be used, then how?
    static{ 
        int a=5;
        double x=4.1;
    }

    //why this does not give any error because of redecleration of integer a?
    static int a=4;

    public static void main(String[] args) {
        System.out.println(a+"");//the output is 4
    }

}

This block 这个块

static{ 
    int a=5;
    double x=4.1;
}

is known as a static initializer. 被称为静态初始化器。 It is used to initialize static fields when more than one statement may be necessary to initialize a field. 当初始化字段可能需要多个语句时,它用于初始化static字段。

But here, you're not actually initializing any static variables. 但是在这里,你实际上并没有初始化任何静态变量。 You just declared two local variables. 您刚刚声明了两个局部变量。

This is the line that counts: 这是重要的一行:

static int a=4;

Your static block opens a new scope: 您的静态块将打开一个新范围:

static{ 
    int a=5;
    double x=4.1;
}

Inside this scope, a and x are created as local vairables , and once the scope ends, they disappear, just like with any other scope, static or not. 在此范围内, ax被创建为本地可变量 ,并且一旦范围结束,它们就会消失,就像任何其他范围一样,静态或不静态。

This is why it does not conflict with the static member 'a', which is initialized to 4 , resulting in that value being printed out. 这就是为什么它与“A”,其被初始化为静态成员冲突4 ,从而导致该值被打印出来。

It's a static initializer . 这是一个static initializer It's executed when the class is loaded. 它在加载类时执行。 You can think of it as class constructor. 您可以将其视为class constructor.

static{ 
        int a=5;
        double x=4.1;
}

why this does not give any error because of redecleration of integer a? 为什么这不会因为重整整数a而给出任何错误?

static int a=4;

There are two local variables and they don't conflict as 'a' is inside the 'static' block. two local variables ,它们don't conflict as 'a' is inside the 'static' block. and the other variable 'a' is in class level . 而另一个变量'a'在class level

this is not an answer just tested what I understand from the answer playing with code I got below results 这不是一个答案刚刚测试了我从答案中得到的理解我在下面得到的代码结果

public class MyClass {

    static int a=6;
    static double x=6.1;

    static{ 
        int a=5;
        double x=4.1;
        initialize(a, x);
    }

    public static void main(String[] args) {
        System.out.println("value of a = "+a);//the output is value of a = 5
        System.out.println("value of x = "+x);//the output is value of x = 4.1
    }

    static void initialize(int a1, double x1){
        a=a1;
        x=x1;
    }
}

another shot 另一个镜头

public class MyClass {

    static{ 
        int a=5;
        double x=4.1;
        initialize(a, x);
    }

    static int a=6;
    static double x=6.1;

    public static void main(String[] args) {
        System.out.println("value of a = "+a);//the output is value of a = 6
        System.out.println("value of x = "+x);//the output is value of x = 6.1
    }

    static void initialize(int a1, double x1){
        a=a1;
        x=x1;
    }
}

There are two questions, so you'll get two answers. 有两个问题,所以你会得到两个答案。

  1. It's called static initializer block, it will be copied to every constructor, those variables are local to the block, you could use them within that block to initialize something but they should be constants probably in that case. 它被称为静态初始化块,它将被复制到每个构造函数,这些变量是块的本地变量,您可以在该块中使用它们来初始化某些东西,但它们应该是常量,在这种情况下。
  2. Two reasons, it's not local to that block. 有两个原因,它不是那个块的本地。 And one would shadow the other if there was a sub-block. 如果存在子块,则会影响另一个。

The block

 static{

 }

is called a static initializer. 被称为静态初始化器。 It is intended to work like a constructor for a Class instance (NOT an Object instance). 它的作用类似于Class实例的构造函数(不是Object实例)。 The reason the static line does not give any error is because the variables declared and initialized in the static block are only scoped to that block. 静态行没有给出任何错误的原因是因为在静态块中声明和初始化的变量只限于该块。 Once the block has completed execution, those variables go out of scope and no longer apply. 块完成执行后,这些变量超出范围,不再适用。 The line 这条线

 static int a=4;

however is Class scoped, so it refers to a completely different variable despite having the same name, in much the same way that the two variables with the same name for the following code refer to two different variables: 但是它是类范围的,所以它引用了一个完全不同的变量,尽管它具有相同的名称,这与下面代码中具有相同名称的两个变量引用两个不同变量的方式非常相似:

 public MyObject{
   private int value;

   public MyObject(int value){
     this.value = value;  // "this" means this instance and removes any ambiguity 
                          // for the compiler
   }
 }

In both cases, the scope of the variables are different and the compiler treats them as two distinct variables. 在这两种情况下,变量的范围都不同,编译器将它们视为两个不同的变量。

The static block can be used to initialize objects that you normally wouldn't in its constructor, and almost never for primitives: 静态块可用于初始化您通常不会在其构造函数中使用的对象,并且几乎从不用于基元:

public class Foo {

    static Bar soap = new Bar();
    static {
        soap.doSomething();
        soap.removeSuds();
        Bar.doSomethingElse(soap);
    }

    ...
}

I think if you see this link, may be a chance to satisfy your eagerness. 我想如果你看到这个链接,可能是一个满足你的渴望的机会。

http://www.jusfortechies.com/java/core-java/static-blocks.php http://www.jusfortechies.com/java/core-java/static-blocks.php

static { 
    int a=5;
    double x=4.1;
}

The purpose of the above block is make the code inside it execute before the main() method does. 上面这个块的目的是让它内部的代码在main()方法之前执行。

Whenever one open's a block in java and declare something inside it, here a static block with variables a and x, become local to that particular block, ie a and x can't be accessed outside the static block. 每当在java中打开一个块并在其中声明一些内容时,这里一个带有变量a和x的静态块变为该特定块的本地,即a和x不能在静态块之外访问。


For more info on scope and lifetime of variables in java refer to following links: 有关java中变量的范围和生命周期的更多信息,请参阅以下链接:

http://www.cs.umd.edu/~clin/MoreJava/Objects/local.html http://www.cs.umd.edu/~clin/MoreJava/Objects/local.html
http://www.c4learn.com/java/java-variable-scope/ http://www.c4learn.com/java/java-variable-scope/

So, the static block in this code is there to just confuse you, it does not have any impact on the execution or result of the program in your case. 因此,此代码中的静态块只会让您感到困惑,它对您的案例中的程序执行或结果没有任何影响。

After the execution of static block, we've moved out of it thus destroying it's local resources, ie a and x. 在执行静态块之后,我们已经移出它,从而破坏了它的本地资源,即a和x。 Now, according to Java, there doesn't exist any variable named a , a new variable with the same name can be initialized. 现在,根据Java,不存在任何名为a的变量,可以初始化具有相同名称的新变量。

@ismail - In Java, all code is executed from top-to-bottom order like any other language. @ismail - 在Java中,所有代码都像其他任何语言一样从上到下执行。 Assuming you that all static blocks are executed before main() method is called. 假设您在调用main()方法之前执行所有静态块。 So consider a case where you have two static blocks: 所以考虑一下你有两个静态块的情况:

public class MyClass {
    static {
        System.out.println("Static Block 1");
    }
    static {
        System.out.println("Static Block 2");
    }
}

The output of above code would be 上面代码的输出将是
Static Block 1
Static Block 2

Something similar is done by you in the your 1st code. 您在第一个代码中完成了类似的操作。 1. You declared some static instance variables. 1.您声明了一些静态实例变量。 2. You created a static block with some local variable and called a function from that block which could manipulate instance variables. 2.您创建了一个带有一些局部变量的静态块,并从该块调用了一个可以操作实例变量的函数。 3. Due to the flow of Java, firstly instance variables were created and then they were manipulated by your static block. 3.由于Java的流程,首先创建实例变量,然后由静态块操纵它们。 That's how you received modified output. 这就是你收到修改输出的方式。

But in 2nd code, the static instance variables got initialized after the execution of static block, hence you received initial values in the output. 但是在第二个代码中,静态实例变量在执行静态块后被初始化,因此您在输出中接收到初始值。

 static{ 
        int a=5;
        double x=4.1;
    }

declares two LOCAL variables a and x and these are not available beyond the static block. 声明两个LOCAL变量ax ,这些变量在静态块之外是不可用的。

static int a=4; 

is declared at class level and can be used by all methods in the class. 在类级别声明,可以由类中的所有方法使用。

System.out.println(a+""); 

looks for variable a at class level and prints 4 在类级别查找变量a并打印4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM