new
, 그리고 모든 것이 준비되었습니다 :) 여기에서는 우리가 글을 쓸 때 컴퓨터와 Java 머신 내부에서 일어나는 일에 대해 이야기하겠습니다. 예를 들면 다음과 같습니다.
Cat cat = new Cat();
이전에 이에 대해 이야기했지만 만일을 대비하여 다음을 상기시켜 드리겠습니다.
- 먼저 객체를 저장하기 위한 메모리가 할당됩니다.
- 다음으로 Java 머신은 객체에 대한 참조를 생성합니다(이 경우 참조는 Cat cat입니다).
- 마지막으로 변수가 초기화되고 생성자가 호출됩니다(이 프로세스를 자세히 살펴보겠습니다).
public class Vehicle {
public static int vehicleCounter = 0;
private String description = "Vehicle";
public Vehicle() {
}
public String getDescription() {
return description;
}
}
public class Truck extends Vehicle {
private static int truckCounter = 0;
private int yearOfManufacture;
private String model;
private int maxSpeed;
public Truck(int yearOfManufacture, String model, int maxSpeed) {
this.yearOfManufacture = yearOfManufacture;
this.model = model;
this.maxSpeed = maxSpeed;
Vehicle.vehicleCounter++;
truckCounter++;
}
}
이 Truck
클래스는 연도, 모델 및 최대 속도를 나타내는 필드가 있는 트럭을 구현한 것입니다. 이제 우리는 그러한 객체를 하나 만들고 싶습니다.
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
Java 시스템에서 프로세스는 다음과 같습니다.
-
가장 먼저 일어나는 일은 클래스 의 정적 변수가
Vehicle
초기화되는 것 입니다 . 네, 수업Vehicle
이 아니라Truck
. 정적 변수는 생성자가 호출되기 전에 초기화되며 이는 부모 클래스에서 시작됩니다. 이것을 확인해보자.vehicleCounter
클래스 의 필드를Vehicle
10으로 설정하고Vehicle
및Truck
생성자 모두에 표시하려고 합니다.public class Vehicle { public static int vehicleCounter = 10; private String description = "Vehicle"; public Vehicle() { System.out.println(vehicleCounter); } public String getDescription() { return description; } } public class Truck extends Vehicle { private static int truckCount = 0; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(vehicleCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCount++; } }
가 표시될
Truck
때 트럭의 필드가 아직 초기화되지 않았음을 확인하기 위해 의도적으로 생성자의 맨 처음에 println 문을 넣습니다 .vehicleCounter
결과는 다음과 같습니다.
10 10
-
부모 클래스의 정적 변수가 초기화된 후 자식 클래스의 정적 변수가 초기화됩니다. 우리의 경우 이것은 클래스
truckCounter
의 필드 입니다Truck
.다른 필드가 초기화되기 전에 생성자
truckCounter
내부 의 값을 표시하는 또 다른 실험을 해봅시다 .Truck
public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(truckCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }
보시 다시피 생성자가 시작될 때 값 10이 이미 정적 변수에 할당되었습니다
Truck
. -
아직 생성자를 위한 시간이 아닙니다! 변수 초기화가 계속됩니다. 부모 클래스의 비정적 변수는 세 번째로 초기화됩니다. 보시다시피 상속은 객체를 생성하는 과정을 상당히 복잡하게 만들지만 이에 대해 할 수 있는 일은 없습니다. 프로그래밍에서 몇 가지만 기억하면 됩니다. :)
실험으로 클래스
description
의 변수 에 초기 값을 할당한Vehicle
다음 생성자에서 변경할 수 있습니다.public class Vehicle { public static int vehicleCounter = 10; private String description = "Initial value of the description field"; public Vehicle() { System.out.println(description); description = "Vehicle"; System.out.println(description); } public String getDescription() { return description; } }
main()
트럭을 생성하는 메서드를 실행해 보겠습니다 .public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
다음 결과를 얻습니다.
Initial value of the description field Vehicle
이는
Vehicle
생성자가 시작할 때description
필드에 이미 값이 할당되었음을 증명합니다. -
마지막으로 생성자를 위한 시간입니다! 보다 정확하게는 기본 클래스 생성자를 위한 시간입니다. 개체 생성 프로세스의 네 번째 단계에서 호출됩니다.
이것은 또한 확인하기가 매우 쉽습니다. 콘솔에 두 줄을 출력해 봅시다. 하나는
Vehicle
기본 클래스 생성자 내부이고 다른 하나는Truck
생성자 내부입니다.Vehicle
내부 줄이 먼저 표시되는지 확인해야 합니다 .public Vehicle() { System.out.println("Hello from the Vehicle constructor!"); } public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Hello from the Truck constructor!"); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; }
우리는 우리의 방법을 실행
main()
하고 결과를 볼 것입니다:Hello from the Vehicle constructor! Hello from the Truck constructor!
훌륭한. 그것은 우리가 틀리지 않았다는 것을 의미합니다 :) 계속 진행하겠습니다.
-
이제 하위 클래스, 즉 우리 클래스의 비정적 필드를 초기화할 시간입니다
Truck
. 인스턴스화되는 클래스 내의 필드는 다섯 번째 단계까지 초기화되지 않습니다! 놀랍지만 사실입니다 :) 다시 한 번 간단한 검사를 수행합니다. 부모 클래스와 마찬가지로 변수에 초기 값을 지정하고 생성자maxSpeed
에서Truck
생성자가 시작되기 전에 값이 할당되었는지 확인합니다.public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed = 150; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Initial value of maxSpeed = " + this.maxSpeed); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }
콘솔 출력:
Initial value of maxSpeed = 150
보시 다시피 생성자가 시작되면 이미 150입니다!
Truck
maxSpeed
-
자식 클래스 의 생성자
Truck
가 호출됩니다.그리고 이 시점에서 마지막으로 인스턴스화하는 클래스의 생성자가 호출됩니다!
여섯 번째 단계에서만 트럭에 인수로 전달하는 값이 필드에 할당됩니다.
보시다시피 트럭을 "구축"하는 것, 즉 객체 생성 프로세스는 간단하지 않습니다. 그러나 우리는 그것을 가장 작은 부분으로 나눈 것 같습니다 :)
GO TO FULL VERSION