Java에서 static 정적 변수의 초기화 완전 해석
1. 간단한 규칙
먼저 가장 보편적인 JAVA 코드를 살펴보겠습니다.
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);
}
}
class Test1
{
public Test1()
{
Test.a++;
Test.b++;
}
}
여기 콘솔 출력 결과가 뭔지 맞혀볼까요?OK, 혹시 아래의 결과를 알아맞혔을지도 몰라. 그럼 자바에 익숙해져.
0 1
만약 네가 왜 위의 결과를 출력했는지 모르겠다면, 내가 너에게 알려줄게.Java 정적 변수 초기화는 다음 규칙을 따릅니다.
선언할 때 0>>Test1: Test1에서 1>>Test로 설정합니다.a 초기화는 0
2. 복잡한 규칙
알겠습니다. 아래의 코드를 다시 보십시오.
public class A
{
public static int b = B.a;
public static A plus =new A("A");
public static final int finalInt = (int)(Math.random()*100);
public static B p = new B("A");
public static final String finalStr = "finalStr";
public static final Integer finalInteger = new Integer(10);
public static int a = 1;
public static B c = null;
public A(String from)
{
System.out.println("----------- begin A::A ----------------");
System.out.println("A::A, from="+from);
System.out.println("A::A, A.b="+A.b);
System.out.println("A::A, A.finalInt="+A.finalInt);
System.out.println("A::A, B.a="+B.a);
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, A.b="+A.b);
System.out.println("main, B.t="+B.t);
System.out.println("main, C.a="+C.a);
}
}
class B
{
public static int t = A.a;
public static A plus = new A("B");
public static int a = 1;
public B(String from)
{
System.out.println("----------- begin B::B ----------------");
System.out.println("B::B, from="+from);
System.out.println("B::B, B.a="+B.a);
System.out.println("B::B, A.a="+A.a);
System.out.println("B::B, A.p="+A.p);
System.out.println("B::B, A.plus="+A.plus);
System.out.println("B::B, A.finalInt="+A.finalInt);
System.out.println("B::B, A.finalInteger="+A.finalInteger);
System.out.println("B::B, A.finalStr="+A.finalStr);
System.out.println("----------- end B::B ----------------");
}
}
class C
{
public static final A a = new A("C");
}
이것 괜찮아요?나는 테스트를 하면서 썼기 때문에 알아맞히지 못했다.하하콘솔 출력 결과:
----------- begin A::A ----------------
A::A, from=B
A::A, A.b=0
A::A, A.finalInt=0
A::A, B.a=0
A::A, B.plus=null
----------- end A::A ----------------
----------- begin A::A ----------------
A::A, from=A
A::A, A.b=1
A::A, A.finalInt=0
A::A, B.a=1
A::A, B.plus=A@a90653
----------- end A::A ----------------
----------- begin B::B ----------------
B::B, from=A
B::B, B.a=1
B::B, A.a=0
B::B, A.p=null
B::B, A.plus=A@1fb8ee3
B::B, A.finalInt=61
B::B, A.finalInteger=null
B::B, A.finalStr=finalStr
----------- end B::B ----------------
main, A.b=1
main, B.t=0
----------- begin A::A ----------------
A::A, from=C
A::A, A.b=1
A::A, A.finalInt=61
A::A, B.a=1
A::A, B.plus=A@a90653
----------- end A::A ----------------
main, C.a=A@61de33
이 결과는 네가 알아맞히지 못했지, 하하.프로그램의 실행 결과를 한마디 한마디로 설명하려면 그래도 매우 적절한 편폭을 가져야 한다.자바 정적 변수 초기화에 따른 규칙을 직접 작성합니다.
첫 번째 단락의 규칙은 여전히 유효하지만, 단지 건전하지 않을 뿐이다.
게다가static한정된 필드는 이른바 클래스 필드입니다. 즉, 이 필드의 소유자는 대상이 아니라 클래스입니다.얼마나 많은 대상을 만들든지 간에static 데이터는 하나밖에 없습니다.
클래스 내에서는 항상 static 필드를 초기화하고 일반 필드를 초기화합니다.이어서 구조기를 초기화하다.그러나 이 클래스의 대상을 만들지 않으면 이 대상은 초기화되지 않고 한 번만 실행됩니다.
아래 코드와 같이 StaticInitialization 클래스에서 static Table table = new Table () 을 초기화합니다.그런 다음 Table 객체를 초기화합니다. 그렇지 않으면 초기화되지 않습니다.
class Bowl {
Bowl(int marker) {
print("Bowl(" + marker + ")");
}
void f1(int marker) {
print("f1(" + marker + ")");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table() {
print("Table()");
bowl2.f1(1);
}
void f2(int marker) {
print("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard() {
print("Cupboard()");
bowl4.f1(2);
}
void f3(int marker) {
print("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String[] args) {
print("Creating new Cupboard() in main");
new Cupboard();
print("Creating new Cupboard() in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
출력:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
표시된 정적 초기화 (정적 블록)여러 개의 초기화 문장을 하나의static 괄호 안에 싸서 정적 블록이라고 하는데 사실은 여러 개의static를 합쳐서 쓴 것이다. 본질은 같다.객체나 클래스에 처음 액세스하는 필드를 처음 만들 때만 실행되며 한 번만 실행됩니다.
class Cup {
Cup(int marker) {
print("Cup(" + marker + ")");
}
void f(int marker) {
print("f(" + marker + ")");
}
}
class Cups {
static Cup cup1;
static Cup cup2;
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups() {
print("Cups()");
}
}
public class ExplicitStatic {
public static void main(String[] args) {
print("Inside main()");
Cups.cup1.f(99); // (1)
}
// static Cups cups1 = new Cups(); // (2)
// static Cups cups2 = new Cups(); // (2)
}
출력:
Inside main()
Cup(1)
Cup(2)
f(99)
비정적 인스턴스 초기화이것은 별로 할 말이 없다. 바로 일반 초기화이다. 순서대로 실행하면 여러 번 실행할 수 있다.
class Mug {
Mug(int marker) {
print("Mug(" + marker + ")");
}
void f(int marker) {
print("f(" + marker + ")");
}
}
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
print("mug1 & mug2 initialized");
}
Mugs() {
print("Mugs()");
}
Mugs(int i) {
print("Mugs(int)");
}
public static void main(String[] args) {
print("Inside main()");
new Mugs();
print("new Mugs() completed");
new Mugs(1);
print("new Mugs(1) completed");
}
}
Inside main()
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs()
new Mugs() completed
Mug(1)
Mug(2)
mug1 & mug2 initialized
Mugs(int)
new Mugs(1) completed
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.