programing

스태틱 수식자는 이 코드에 어떤 영향을 미칩니까?

yoursource 2022. 9. 4. 23:38
반응형

스태틱 수식자는 이 코드에 어떤 영향을 미칩니까?

코드는 다음과 같습니다.

class A {
    static A obj = new A();
    static int num1;
    static int num2=0;

    private A() {
        num1++;
        num2++;
    }
    public static A getInstance() {
        return obj;
    }
}

public class Main{
    public static void main(String[] arg) {
        A obj = A.getInstance();
        System.out.println(obj.num1);
        System.out.println(obj.num2);
    }
}

출력은출력은1 0하지만 이해할 수 없다.이해할 수 없어요.

누가 설명 좀 해줄래?

Java 에서는 2개의 단계가 발생합니다.1 .신원확인, 2.실행

  1. 식별 단계에서는 모든 정적 변수가 검출되고 기본값으로 초기화됩니다.

    그래서 지금 이 값: 있다.이제값은 다음과 같습니다.
    A obj=null
    num1=0
    num2=0

  2. 두 번째 단계인 실행은 위에서 아래로 시작됩니다.Java에서는 첫 번째 스태틱멤버부터 실행이 시작됩니다.
    이게 바로 첫번째 정적 변수는 첫번째 정적 변수는다음과 같습니다.static A obj = new A();, 그렇게 처음과 따라서의 그 값 먼저 생성자를 호출하 해당 변수의 개체를 만들고 생성자를 호출합니다 그 변수의 개체를 만들 것이다.따라서 값은num1 ★★★★★★★★★★★★★★★★★」num2된다가 되1.
    그리고 그리고, 다시 그리고 다시,static int num2=0;,실행되기 때문에게 실행될 것이다.num2 = 0;.

이제 컨스트럭터가 다음과 같다고 가정합니다.

 private A(){
    num1++;
    num2++;
    System.out.println(obj.toString());
 }

이것은 이렇게를 던질 것이다 하면NullPointerException~하듯이로obj여전히 아직의 참고언급이 없다 대한 에가 있지 않았다.class A.

무엇이 음, 그건…static되는 modifier는 변수가 합니다.modifier는 변수입니다른른른른...밖에 없다num1및 1개의 "displaces, 1" 합니다.num2★★★★★★ 。

(게다가 정적 변수는 이름이 어디에나 표시되지 않는 것을 제외하고 일부 다른 언어의 전역 변수와 같습니다.로서 선언되어도public static현재 클래스 또는 슈퍼 클래스에서 선언된 이름 또는 정적 Import를 사용하여 Import된 이름만 표시됩니다.그게 차이점이에요.진정한 글로벌은 어느 곳에서도 조건 없이 볼 수 있습니다.)

을 할 때obj.num1 ★★★★★★★★★★★★★★★★★」obj.num2실제 명칭은 다음과 같은 스태틱 변수를 말합니다.A.num1 ★★★★★★★★★★★★★★★★★」A.num2했을 때num1 ★★★★★★★★★★★★★★★★★」num2아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.

이 예제의 혼란스러운 주름은 클래스 초기화입니다.클래스는 먼저 모든 스태틱 변수를 초기화하고 나서 선언된 스태틱인테셜라이저(및 스태틱인테셜라이저 블록)를 클래스에 표시되는 순서대로 실행하여 초기화됩니다.이 경우 다음과 같이 됩니다.

static A obj = new A();
static int num1;
static int num2=0;

다음과 같은 현상이 발생합니다.

  1. 으로 시작합니다.A.objnull ★★★★★★★★★★★★★★★★★」A.num1A.num20 입니다.

  2. 번째 「 」 )A.obj)은는)의 인스턴스를 .A() " "의A증분A.num1그리고.A.num2선언이 완료되면A.num1그리고.A.num2둘 다이다1,그리고.A.obj새로 건설된 것을 말한다.A사례.

  3. 두 번째 선언(A.num1)에는 이니셜라이저가 없기 때문에A.num1변하지 않습니다.

  4. 세 번째 선언(A.num2)에는 0을 할당하는 이니셜라이저가 있습니다.A.num2.

따라서 클래스 초기화 종료 시A.num11그리고.A.num20...그것은 당신의 인쇄문구에 나타난 것입니다.

이 혼란스러운 동작은 실제로는 스태틱 초기화가 완료되기 전에 인스턴스를 만들고 있으며, 사용하고 있는 컨스트럭터가 아직 초기화되지 않은 스태틱에 의존하여 수정하고 있기 때문입니다.이것은 실제 코드에서 하지 말아야 할 것입니다.

1.0이 맞습니다.

클래스가 로드되면 모든 정적 데이터가 oder로 초기화됩니다.디폴트 int는 0 입니다.

  • 먼저 A가 생성됩니다.num1과 num2가 1과 1이 된다.
  • 보다static int num1;아무것도 하지 않다
  • 보다static int num2=0;0 ~ num2 로 써집니다.

스태틱 이니셜라이저의 순서에 의한 것입니다.클래스의 정적 표현식은 하향식으로 평가됩니다.

가장 먼저 호출되는 것은 의 구축자입니다.A이 경우,num1그리고.num2둘 다 1:

static A obj = new A();

그리고나서,

static int num2=0;

를 호출하여 num2=0 을 다시 설정합니다.

그게 이유다num11과num20 입니다.

참고로 생성자는 정적 변수를 수정하지 않아야 합니다. 이는 매우 나쁜 설계입니다.대신 Java에서 Singleton을 구현하는 다른 방법을 시도해 보십시오.

JLS 섹션은 § 12.4.2입니다.

상세 초기화 절차:

9. 다음으로 클래스의 클래스 변수 이니셜라이저와 스태틱 이니셜라이저 또는 인터페이스의 필드 이니셜라이저를 텍스트 순서로 실행합니다.단, 최종 클래스 변수와 값이 컴파일 시간 상수인 인터페이스의 필드는 먼저 초기화됩니다.

따라서 3개의 정적 변수가 텍스트 순서대로 하나씩 초기화됩니다.

그렇게

static A obj = new A();
//num1 = 1, num2 = 1;
static int num1;
//this is initilized first, see below.
static int num2=0;
//num1 = 1, num2 = 0;

순서를 변경하는 경우:

static int num1;
static int num2=0;
static A obj = new A();

결과는 다음과 같습니다.1,1.

주의:static int num1;는 변수 이니셜라이저가 아닙니다.이유는 다음과 같습니다(제8.3.2항).

필드 선언자에 변수 이니셜라이저가 포함되어 있는 경우 선언된 변수에 대한 할당의 의미('15.26)가 지정됩니다.또한 선언자가 클래스 변수(즉, 정적 필드)에 대한 것이라면 변수 이니셜라이저는 평가되고 클래스가 초기화되었을 때 정확히 한 번 할당이 수행됩니다.

이 클래스 변수는 클래스 생성 시 초기화됩니다.이것은, 최초로 발생합니다( 「4.12.5」).

프로그램의 모든 변수는 값을 사용하기 전에 값을 가져야 합니다.각 클래스 변수, 인스턴스 변수 또는 배열 컴포넌트는 작성 시 기본값('15.9, '15.10:타입 바이트의 경우 기본값은 0, 즉 (바이트)0 입니다.short 타입의 경우 기본값은 0, 즉 (short)0 입니다.type int의 경우 기본값은 0, 즉0 입니다.long 타입의 경우 기본값은 0, 즉 0L입니다.float 형식의 경우 기본값은 양의 0, 즉 0.0f입니다.double 타입의 경우 기본값은 양의 0, 즉 0.0d입니다.char 타입의 경우 기본값은 늘 문자, 즉 '\u0000'입니다.boolean 유형의 경우 기본값은 false입니다.모든 기준 유형(θ4.3)에 대해 기본값은 null입니다.

이런 식으로 생각하면 도움이 될 것 같아요.

클래스는 개체의 Blueprint입니다.

개체는 인스턴스화될 때 변수를 가질 수 있습니다.

클래스에는 변수가 있을 수도 있습니다.이것들은 스태틱으로 선언됩니다.따라서 오브젝트 인스턴스가 아닌 클래스로 설정됩니다.

애플리케이션에서는 모든 클래스가 하나의 클래스만 가질 수 있기 때문에 해당 클래스 전용 글로벌 스토리지와 비슷합니다.물론 이러한 정적 변수는 응용 프로그램의 모든 위치에서 액세스 및 수정할 수 있습니다(공용 변수인 경우).

다음은 정적 변수를 사용하여 생성된 인스턴스 수를 추적하는 "Dog" 클래스의 예입니다.

"Dog" 클래스는 클라우드이고 오렌지 상자는 "Dog" 인스턴스입니다.

도그 클래스

더 읽기

이게 도움이 됐으면 좋겠네요!

만약 당신이 사소한 일처럼 느낀다면, 이 생각은 플라톤에 의해 처음 소개되었다.

static 키워드는 Java에서 주로 메모리 관리에 사용됩니다.변수, 메서드, 블록 및 중첩 클래스와 함께 static 키워드를 적용할 수 있습니다.static 키워드는 클래스의 인스턴스가 아닌 클래스에 속합니다.static 키워드에 대한 간단한 설명은 다음과 같습니다.

http://www.javatpoint.com/static-keyword-in-java

위의 답변의 대부분은 정답입니다.하지만 실제로 무슨 일이 일어나고 있는지 설명하기 위해 아래에 몇 가지 수정을 가했습니다.

위에서 여러 번 언급했듯이 클래스 A가 완전히 로드되기 전에 클래스 A의 인스턴스가 생성되고 있습니다.그래서 정상적인 '행동'으로 여겨지는 것은 관찰되지 않는다.이는 덮어쓸 수 있는 컨스트럭터로부터의 호출 메서드와 크게 다르지 않습니다.이 경우 인스턴스 변수가 직관적인 상태가 아닐 수 있습니다.이 예에서는 클래스 변수가 직관적인 상태가 아닙니다.

class A {
    static A obj = new A();
    static int num1;
    static int num2;
    static {
        System.out.println("Setting num2 to 0");
        num2 = 0;
    }

    private A() {
        System.out.println("Constructing singleton instance of A");
        num1++;
        num2++;
    }

    public static A getInstance() {
        return obj;
    }
}

public class Main {

    public static void main(String[] arg) {
        A obj = A.getInstance();
        System.out.println(obj.num1);
        System.out.println(obj.num2);
    }
}

출력은

Constructing singleton instance of A
Setting num2 to 0
1
0

java는 호출되지 않지만 생성될 때까지 정적 또는 비정적 데이터 멤버의 값을 초기화하지 않습니다.

따라서 여기서 num1과 num2가 주로 호출될 때 값으로 초기화됩니다.

num1 = 0+1 및

num2=0;

언급URL : https://stackoverflow.com/questions/20115672/how-does-the-static-modifier-affect-this-code

반응형