컴파일러는 개발자가 기본 생성자를 생성하지 않아도 알아서 생성해줍니다.

 


 

기본 생성자를 만드는 규칙은 다음과 같습니다.

 

  1. 생성자의 이름은 클래스의 이름과 동일하게 선언합니다.
  2. 리턴 타입은 없습니다.
  3. 매개 변수는 없습니다.
  4. 접근 제한자는 클래스를 따라갑니다.

 

다음은 기본 생성자의 예시입니다.

public class Car {
	
    // 명시적으로 생성자를 선언하지 않으면,
    // 자바 컴파일러가 개입 -> 기본 생성자 생성
	
    Car(){
         ;;
    } // default Constructor
	
} // end class

 

 

 

만약 롬복(lombok)이 설치되어 있다면 롬복으로 기본생성자를 만들 수 있습니다.

@Log4j2
@NoArgsConstructor // lombok으로 기본 생성자 생성
public class Car {
	
	
	
} // end class

 

 

하지만 기본 생성자 이외에 인자값을 받는 생성자가 필요한 상황이 있습니다.

@Log4j2
@NoArgsConstructor // 기본 생성자 생성
public class Car {
    private String color; // 인스턴스 필드
    private int cc;
	
    Car(String color, int cc){
        // 외부에서 인자값을 받아 인스턴스 필드 초기화
        this.color = color; 
        this.cc = cc;
    } // Constructor
	
} // end class

 

이렇게 외부에서 값을 받아 인스턴스 필드를 초기화할 때, 인자값을 받는 생성자를 생성합니다.

this객체의 레퍼런스(주소)를 가리키는 것입니다.

 

로그를 통해 알아보겠습니다.

@Log4j2
@NoArgsConstructor
public class Car {
    private String color;
    private int cc;
	
    Car(String color, int cc){
    	log.trace("Car({}, {}) invoked", color, cc);
        // 외부에서 인자값을 받아 필드 초기화
        this.color = color; 
        this.cc = cc;
        
        // Car 클래스에서의 this가 가리키는 주소를 로그로 출력
        log.info("\t + myCar1 : {}",this); 
        
    } // Constructor
	
} // end class

// =====================================================

@Log4j2
public class CarExample {
	
	
	public static void main(String[] args) {
        log.trace("main({}) : invoked", Arrays.toString(args));
		
        Car myCar1 = new Car("검정", 3000);
        
        //CarExample 클래스에서 myCar1이 가리키는 주소를 로그로 출력
        log.info("\t + this : {}", myCar1); 
		
        Car myCar2 = new Car();
	} // main
    
} // end class

 

롬복의 log.info를 통해 출력하면 다음과 같은 주소가 출력됩니다.

12:18:09.971  INFO --- [      main] s.e.Car.<init>:23 - 	 + this : sec07.exam01.Car@c333c60
12:18:09.971  INFO --- [      main] s.e.CarExample.main:15 - 	 + myCar1 : sec07.exam01.Car@c333c60

@ 이후의 값을 보시면 Car 클래스의 this와 CarExample의 myCar1이 동일한 값을 가리키는 것을 알 수 있습니다.

즉, 객체의 주소를 저장하고 있는 것은 참조변수 뿐만 아니라 this 또한 객체의 주소를 저장하고 있습니다.

 

 

 

 

 

주의할 점은, static이 붙은 필드를 초기화할 때에는 오직 static initializer이 해야 합니다.

@Log4j2
@NoArgsConstructor // 기본 생성자 생성
public class Car {
    private String color;
    private int cc;
    private static String company; // 정적 필드
    
    static {
        company = "현대";
    } // static initializer, 정적 블록
	
    Car(String color, int cc){
        // 외부에서 인자값을 받아 필드 초기화
        this.color = color; 
        this.cc = cc;
    } // Constructor
	
} // end class

정적 필드는 해당 클래스에서 생성한 모든 인스턴스(객체)에 공유되는 필드입니다.

반면, 인스턴스 필드는 생성한 각 객체마다 가지고 있는 필드입니다.

정적 블록은 한번만 실행되며, static 필드(정적 필드)를 초기화하기 위해 사용됩니다.

 


 

여기서 클래스의 선언하는 멤버의 종류를 두 가지로 나눌 수 있습니다.

 

1. 인스턴스 필드와 인스턴스 메소드는 각각의 객체의 소속입니다.

2. 정적 필드와 정적 메소드는 "java.lang.Class" 타입의 객체(Clazz)라고 할 수 있습니다.

 

 

Clazz는 너무 추상적이라 이해가 안될수 도 있기 때문에, Clazz 객체를 구해보겠습니다.

구하는 방법은 세 가지가 잇습니다.

1. 참조타입명.class

2. 참조변수.class

3. java.lang.Class.forName("참조타입명"); => 리턴타입 : Clazz

 

코드로 구해보겠습니다.

@Log4j2
public class KoreanExample {
	
	
    public static void main(String[] args) throws ClassNotFoundException{ // 3번 오류 던지기
        log.trace("main({}) invoked", Arrays.toString(args));
		
        1. 참조타입명.class
        java.lang.Class clazz = Korean.class;
        log.info("\t + 1st. clazz: {}", clazz);
		
        2. 참조변수.getClass()
        Korean korean = new Korean();
        log.info("\t + 2nd. clazz : {}", korean.getClass());
        
        3. java.lng.Class.forName("참조타입명"); => 리턴타입 : clazz
        clazz = Class.forName("sec07.exam02.Korean");
        log.info("\t + 3nd. clazz : {}", clazz);
        
    } // main
	
} // end class

// ============================================

@Log4j2
@NoArgsConstructor
public class Korean {
	
} // end class

 

출력하면 다음과 같은 로그가 출력됩니다.

14:21:50.490  INFO --- [      main] s.e.KoreanExample.main:21 - 	 + 1st. clazz: class sec07.exam02.Korean
14:21:50.491  INFO --- [      main] s.e.KoreanExample.main:24 - 	 + 2nd. clazz : class sec07.exam02.Korean
14:21:50.491  INFO --- [      main] s.e.KoreanExample.main:27 - 	 + 3nd. clazz : class sec07.exam02.Korean

 

정적 필드와 메소드에 대해서 동일한 clazz가 출력되는 것을 볼 수 있습니다.

'Java' 카테고리의 다른 글

인터페이스  (0) 2023.07.25
Getter Setter  (0) 2023.07.21
args  (0) 2023.07.18
JAVA 14 Switch Expressions  (0) 2023.07.17
제곱근 필터링  (0) 2023.07.15

+ Recent posts