정규화(Normalization)은 다양한 정보를 포함하고 있는 하나의 테이블을 각 정보에 맞게 쪼개는 작업을 의미합니다.

따라서, 정규화는 '무손실 분해'라고 합니다.

 

 


 

 

정규화는 각각의 정보를 별도의 릴레이션으로 무손실 분해해서 이상현상을 제거하는 것에 목적을 두고 있습니다.

 

이러한 정규화는 6가지로 나눌 수 있지만 일반적으로 세 종류의 정규화를 주로 사용합니다.

정규화 단계를 거쳐야 다음 정규화 과정을 수행할 수 있습니다.

 

 

# 정규화

 

  1.  1NF 릴레이션
  2.  2NF 릴레이션
  3.  3NF 릴레이션
  4.  BCNF 릴레이션
  5.  4NF 릴레이션
  6.  5NF 릴레이션

 

 

 

1. 제 1정규형(1NF)

 

1NF는 다중값 속성을 제거하는 단계입니다.

즉, 정규화를 수행하는 릴레이션의 모든 속성값이 원자(단일)값을 가지면 1NF라고 합니다.

 

 

2. 제 2정규형(2NF)

 

2NF는 하나의 릴레이션에 두 개의 릴레이션이 종속되어 있다면 분해하는 단계입니다.

즉, 기본키가 아닌 속성이 기본키에 완전 함수 종속일 때 2NF라고 합니다.

 

 

3. 제 3정규형(3NF)

 

비이행적(non-transitive)으로 종속할 때 3NF라고 합니다.

이행적 종속이란 A = B, B = C일때, A = C가 성립되는 함수 종속성입니다.

 

 

 

 

 

'Database > SQL' 카테고리의 다른 글

외부 조인  (0) 2023.08.21
그룹화  (0) 2023.08.17
인라인 뷰  (0) 2023.08.17
외래 키  (1) 2023.08.16
데이터 사전  (0) 2023.08.16

 

 

 

web.xml을 웹 애플리케이션의 설정파일이라고 할 수 있습니다.

즉, 웹 애플리케이션에 포함된 모든 종류의 구성요소(Servlet, JSP와 같은 Component)를 설정합니다.

 

 


 

 

사양에 따라 web.xml을 설정해야 합니다.

 

 

# Tomcat 9.0

<?xml version="1.0" encoding="UTF-8"?>

    <web-app 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    version="4.0">

 

 

# Tomcat 8.0

<?xml version="1.0" encoding="UTF-8"?>

    <web-app 
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

 

 

# Tomcat 7.0

<?xml version="1.0" encoding="UTF-8"?>

    <web-app 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

 

 

 

web.xml에서 설정 이후, 지역 설정 Project Facets에서 잘 적용됐는지 확인할 수 있습니다.

 

 

 

 

 

 

'웹 표준 > Servlet' 카테고리의 다른 글

Session Tracking  (0) 2023.09.14
FrontController, Command Patterns  (0) 2023.09.13
Request  (0) 2023.09.13
DTO, DAO, VO  (0) 2023.09.12
Connection Pool  (0) 2023.09.08

[ 최종수정일 - 2023_09_20 ]

 

 

pom.xml Dependency List

 

 

 Move to Maven Repository 


 

 

 

 

라이브러리 이름을 클릭하면 해당 라이브러리의 Maven Repository로 이동합니다.

 

  • log4j-slf4j-impl / log4j-core
    로깅 라이브러리


  • JUnit
    테스트 코드 라이브러리

  • Lombok
    어노테이션 라이브러리


  • javax.servlet-api / javax.servlet.jsp-api
    Servelt, JSP 표준대로 구현된 라이브러리, 구현체는 자동으로 추가

  • jstl
    jstl 문법 구현을 위한 라이브러리

  • Spring Security Core
    암호화 알고리즘 구현을 위한 라이브러리

  • Assertj-Core
    참조 변수의 값이 null인지 검증하는 라이브러리입니다.

 

 

 

 

# JSON serialize / de-serialize

  • Gson
    구글에서 제작한 JSON 변환 라이브러리입니다.

  • Genson
    변환 라이브러리입니다.

  • **Jackson**
    Spring에서 자주 사용되는 변환 라이브러리입니다.

  • JSON IO
    변환 라이브러리입니다.
    다른 변환 라이브러리와는 다르게 JSON IO는 자바 클래스를 반드시 CLASSPATH에 가지고 있어야 합니다.


 


 

 

# MyBatis

  • MyBatis
    아파치의 마이바티스 라이브러리

  • Log4jdbc Log4j2 JDBC4
    DriverSpy 설정을 위한 라이브러리(Optional)

  • Ojdbc8
    #Oracle JDBC Driver 참조

 

 


 

 

# Oracle JDBC Driver

  • OJdbc8
    오라클을 jdbc로 연결하기 위한 라이브러리, 필요에 따라 <dependency> 내에 Optional exclusions를 추가합니다.


Optional exclusions

더보기
  • simplefan
  • ons
  • rsi
  • ucp
  • xdb
  • xmlparserv2

 

 

 


 

 

 

 

 

 

 

'Spring boot > Maven' 카테고리의 다른 글

JUnit5  (0) 2023.08.23
JUnit4  (0) 2023.08.22
Maven dependency 추가하기  (0) 2023.08.21
pom.xml(메이븐 설정파일)  (0) 2023.07.28

 

 

 

Junit5 테스트 코드 작성 가이드입니다.

 

 


 

 

JUnit5는 POJO 기반으로 작성되며, 기본 생성자가 필요합니다.

 

 

 

JUnit5는 JUnit4와 다르게 어노테이션이 매우 다양합니다.

사용되는 어노테이션은 두 가지로 구분합니다.

 

 


 

 

타입 선언부 어노테이션

 

  • @TestInstance :
    각각의 단위 테스트 메서드를 수행할 때, 안전한 결과를 얻어내기 위해 테스트 클래스로부터
    테스트 객체를 어떠한 기준으로 생성할 지 결정하는 어노테이션입니다.
    해당 어노테이션의 속성은 'PER_CLASS'와 'PER_METHOD'가 이며 defualt는 'PER_CLASS'입니다.

    - PER_METHOD(기본값) : 단위 테스트 메서드마다 테스트 객체 생성 후 테스트 메서드를 수행합니다.

    - PER_CLASS : 하나의 테스트 객체만 생성 후, 모든 단위 테스트 메서드를 수행합니다.

    다만 PER_METHOD는 메모리에 부담을 주기 때문에 개발환경을 고려하여 설정해야 합니다.

  • @TestMethodOrder :
    모든 단위 테스트 메서드의 실행순서의 기준과 방법을 설정합니다.
    다양한 속성이 있지만, 주로 OrderAnnotation(@Order, 서수)을 사용합니다.

 

테스트 클래스 블록 어노테이션

 

전처리 어노테이션

 

  • @BeforeAll :
    단위 테스트 메서드 수행 시, 오직 한 번만 수행되는 전처리입니다.

  • @BeforeEach :
    단위 테스트 메서드 수행 시 매번 수행되는 전처리입니다.(JUnit4의 @Before와 동일)

  • @AfterAll :
    단위 테스트 메서드 수행 시, 오직 한 번만 수행되는 후처리입니다.

  • @AfterEach :
    단위 테스트 메서드 수행 시 매번 수행되는 후처리입니다.(JUnit4의 @Before와 동일)

 

 

 

 

후처리 어노테이션

 

  • @Disabled :
    단위테스트 메서드를 제외시킵니다.

  • @Tag :
    단위 테스트의 성격(fast,normal, slow)을 표시합니다.

  • @Test :
    메서드가 단위 테스트용임을 표시합니다.

  • @Order :
    단위 테스트 메서드의 수행 순서를 결정합니다.

  • @DisplayName :
    테스트 도구에 표시되는 단위 테스트의 이름입니다.
    JUnit View에서 해당 어노테이션으로 설정한 이름으로 보여줍니다.

  • @Timeout :
    JUnit4에서는 @Test의 속성이었습니다.
    하지만, JUnit5에서는 다양한 시간 단위로 테스트의 임계 소요 시간을 정의할 수 있도록 분리하여 사용합니다.
    속성으로 value와 unit이 있습니다.

    예를 들어, 0.5초 안에 테스트를 종료해야 한다면 다음과 같이 코드를 작성할 수 있습니다.
    @Timeout(value = 500L, unit = TimeUnit.MILLISECONDS)

 

 


 

 

 

다음은 간단한 JUnit5 테스트 코드 작성법입니다.

@Log4j2
@NoArgsConstructor

// 1. 타입 선언부에 적용해야할 JUnit Jupyter Annotations입니다.
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JUnitJupiterTemplateTests {
	
	
    @BeforeAll
    void beforeAll() { // 1회성 전처리
        log.trace("beforeAll() invoked.");
        
        // TODO here.
    } // beforeAll
	
    @BeforeEach
    void beforeEach() { // 매번 수행되는 전처리
        log.trace("beforeEach() invoked.");
        
        // TODO here.
    } // beforeEach
	
    @AfterAll
    void afterAll() { // 1회성 후처리
        log.trace("afterAll() invoked.");
        
        // TODO here.
    } // afterAll
	
    @AfterEach
    void afterEach() { // 매번 수행되는 후처리
        log.trace("afterEach() invoked.");
        
        // TODO here.
    } // afterEach
	
    // ------------------------------------------------
	
    @Disabled
    @Tag("fast")
    @Test
    @Order(1)
    @DisplayName("contextLoads")
    @Timeout(value = 500L, unit = TimeUnit.MILLISECONDS)
    void contextLoads() { // 단위 테스트 메서드
        log.trace("contextLoads() invoked.");
    } // contextLoads
	
} // end class

 

 

 

 

'Spring boot > Maven' 카테고리의 다른 글

Maven Dependency List  (0) 2023.09.01
JUnit4  (0) 2023.08.22
Maven dependency 추가하기  (0) 2023.08.21
pom.xml(메이븐 설정파일)  (0) 2023.07.28

 

 

 

JUnit4의 테스트 클래스 작성에 대한 가이드입니다.

 

 


 

 

테스트 클래스는 POJO(Plain Old Java Object) 기반으로 작성되며,

세 가지 어노테이션을 제공합니다.

 

  • @Before :
    매 단위 테스트 메서드 수행 전, 전처리 수행합니다.
    단위 테스트에 필요한 자원 객체를 생성하는 작업을 수행합니다.

  • @Test :
    단위 테스트 메서드임을 JUnit에게 알려줍니다.
    추가적인 어노테이션의 기능으로 timeoutexpected가 있습니다.

  • @After :
    매 단위 테스트 메서드 수행 후에, 후처리 수행합니다.

    전처리에서 생성 및 획득한 자원 객체를 해제하는 작업을 수행합니다.

 

 

여기서 단위 테스트는 1개의 기능을 테스트하는 것을 의미합니다.

 

 

기본적인 테스트 클래스 세팅은 다음과 같습니다.

 

@Log4j2
@NoArgsConstructor
public class AppTest  {
	
	
    @Before
    public void setUp() {
        // 전처리(Pre-processing), Optional
        log.trace("setUp() invoked.");
    } // setUp
	
    @Test
    public void testXXX() {
        log.trace("testXXX() invoked.");
    } // testXXX
	
    @After
    public void tearDown() {
        // 후처리(Post-processing), Optional
        log.trace("tearDown() invoked.");
    } // tearDown

} // end class

 

 

여기서 주의할 점은,  테스트 클래스는 반드시 기본 생성자를 가져야 합니다.

저는 Lombok을 사용하고 있으므로, 어노테이션을 통해 생성하였습니다.

필요에 따라 필드 생성도 가능합니다.

 

테스트 클래스를 실행하면 JUnit View에 테스트 결과를 보여줍니다.

 

 


 

 

만약 전처리/후처리/단위 테스트 메서드들 중 메서드 블록안에서 예외 발생 가능한 코드가 있다면, 반드시 예외 처리없이 위로 던져야 합니다.

그 이유는 위로 던지면 JUnit Test Framework가 받게 되고, JUnit은 받은 예외를 통해 테스트 통계 자료를 산출하기 위함입니다.

 

즉, 컴파일러가 오류을 체크했다면 throws Exception를 통해 오류를 모두 위로 던지면 됩니다.

 

 

 

 

 

 

 

'Spring boot > Maven' 카테고리의 다른 글

Maven Dependency List  (0) 2023.09.01
JUnit5  (0) 2023.08.23
Maven dependency 추가하기  (0) 2023.08.21
pom.xml(메이븐 설정파일)  (0) 2023.07.28

 

 

 

Maven Project을 참고하여 pom.xml에 라이브러리를 추가할 수 있습니다.

저는 JUnit을 추가하겠습니다.

 

 


 

 

JUnit은 대표적으로 4, 5 두 가지 빌드가 있는데, junit5를 설정하겠습니다.

 

 

JUnit은 pom.xml에 하나의 의존성만 설정하면 됩니다.

 

  • JUnit Jupiter Api

 

의존성을 추가하기 위해 Maven Repository를 방문합니다.

 

검색창에 JUnit을 입력합니다.

 

Maven Repository

 

모든 의존성 모두 같은 방식이므로 다른 의존성 또한 동일하게 진행됩니다.

 

의존성을 클릭합니다.

 

Maven Repository

 

빨간색 바탕의 빌드 버전은 사용하시면 안됩니다.

 

가장 최신 버전인 5.10.0을 클릭합니다.

 

Maven Repository

 

Maven 메뉴에서 해당 코드를 클릭하면 복사됩니다. 

복사한 코드를 Maven Project의 빌드 설정 파일인 pom.xml에 paste합니다.

 

 

  <dependencies>
	  
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.10.0</version>
      <scope>test</scope>
    </dependency>
    
    <!-- 기타 의존성 -->
    
  </dependencies>

 

 

 

'Spring boot > Maven' 카테고리의 다른 글

Maven Dependency List  (0) 2023.09.01
JUnit5  (0) 2023.08.23
JUnit4  (0) 2023.08.22
pom.xml(메이븐 설정파일)  (0) 2023.07.28

 

 

 

OUTER JOIN은 한 쪽 테이블의 모든 행을 기준으로 다른 테이블을 JOIN합니다.

예를 들어, LEFT OUTER JOIN이라면 왼쪽 테이블의 모든 행을 기준으로 오른쪽 테이블을 JOIN합니다.

 

 


 

 

다음은 OUTER JOIN에 대한 쿼리입니다.

 

-- Oracle LEFT OUTER JOIN --

SELECT
  e.last_name AS 사원명,
  e.employee_id AS 사원번호,
  m.last_name AS 관리자명,
  m.employee_id AS 관리자사번
FROM
  employees e,
  employees m
WHERE
  e.manager_id = m.employee_id (+);
  
 
 
 -- Ansi LEFT OUTER JOIN --
 
SELECT
  e.last_name AS 사원명,
  e.employee_id AS 사원번호,
  m.last_name AS 관리자명,
  m.employee_id AS 관리자사번
FROM
  employees e LEFT OUTER JOIN employees m -- OUTER 키워드 생략 가능 --
  ON e.manager_id = m.employee_id;

 

RIGHT OUTER JOIN도 동일한 개념으로 동작합니다.

 

 

그런데 Ansi JOIN에서만 있는 FULL OUTER JOIN이 있습니다.FULL OUTER JOIN은 두 테이블의 모든 행을 결합하되, NULL값을 모두 포함하여 결합합니다.

 

-- Ansi FULL OUTER JOIN --

SELECT
  e.last_name AS 사원명,
  e.employee_id AS 사원번호,
  m.last_name AS 관리자명,
  m.employee_id AS 관리자사번
FROM
  employees e FULL OUTER JOIN employees m -- OUTER 키워드 생략 가능 --
  ON e.manager_id = m.employee_id;

 

 

 

 

'Database > SQL' 카테고리의 다른 글

정규화  (0) 2023.09.06
그룹화  (0) 2023.08.17
인라인 뷰  (0) 2023.08.17
외래 키  (1) 2023.08.16
데이터 사전  (0) 2023.08.16

 

 

 

직렬화는 Object의 필드들(정보)을 바이트 코드로 변환하는 것을 의미합니다.

역직렬화는 바이트 코드들을 본래의 필드로 복구하는 것을 의미합니다.

 

 


 

 

클래스를 생성할 때 Serializable를 Implements 해야 합니다.

만약 출력하고 싶지 않은 필드가 있다면 해당 필드에 transient 키워드를 붙이면 됩니다.

 

다음은 직렬화에 대한 코드입니다.

 

 

ClassA

 

@Data
public class ClassA implements Serializable {
    private int field1;             // 일반 필드 생성
    ClassB field2 = new ClassB();   // ClassB 객체 생성
    static int field3;              // 정적 필드 생성
    transient int field4;           // 한정자(transient) 필드 생성, 직렬화 제외
	
} // end class

 

 

클래스B와 클래스C는 간단한 필드만 선언되어 있습니다.

 

 

ClassB

 

@ToString
@NoArgsConstructor
public class ClassB implements Serializable {
    int field1;
	
} // end class

 

 

ClassC

 

@ToString
@NoArgsConstructor
public class ClassC implements Serializable {
    int field1;
	
} // end class

 

 

메인 스트림에서 지정한 경로에 필드의 정보를 출력합니다.

 

SeriaizableWriter

public class SerializableWriter {

	
    public static void main(String[] args) throws Exception{
        // @Cleanup 어노테이션으로 자동 자원 해제
        @Cleanup FileOutputStream fos = new FileOutputStream("C:/Temp/Object.dat");
        @Cleanup ObjectOutputStream oos = new ObjectOutputStream(fos);
		
		
        ClassA classA = new ClassA();   // 기본 생성자로 객체 생성
        
        classA.setField1(1);            // 고유속성 초기화
        classA.field2.field1 = 2;       // 부품필드 초기화
        ClassA.field3 = 3;              // 정적필드 초기화
        classA.field4 = 4;              // transient 한정자가 붙은 필드
		
		
        // ClassA타입의 객체를 파일에 출력(ObjectOutputStream)
        oos.writeObject(classA);
        oos.flush();
    } // main
	
} // end class

 

위 실행 클래스가 정상적으로 동작되었다면, Temp 폴더에 Object.dat 파일이 생성됩니다.

 

 

이제 Object.dat 파일을 읽는 실행 클래스를 만들겠습니다.

 

@Log4j2
public class SerializableReader {

    public static void main(String[] args) throws Exception{
        @Cleanup FileInputStream fis = new FileInputStream("C:/Temp/Object.dat");
        @Cleanup ObjectInputStream ois = new ObjectInputStream(fis);
		
		
        ClassA objA = (ClassA) ois.readObject();
		
        log.info("1.field1: {} ", objA.getField1());
        log.info("2.field2.field1: {} ", objA.field2.field1);
        log.info("3.field2: {} ", ClassA.field3);
        log.info("4.field3: {} ", objA.field4);
    } // main

} // end class

 

입력받은 각 필드의 키워드는 다음과 같습니다.

 

  • field1 = classA_private int field1 = 1
  • field2 = classA_classB_int field1 = 2
  • field3 = classA_static int field3 = 3
  • field4 = classA_transient int field4 = 4

 

다음은 출력 결과입니다.

 

조회 결과

 

보시는 것처럼,

Serializable를 Implements하는 클래스에 있는 필드들의 출력 파일을 입력받았는데

field3 과 field4는 결과값이 없는 것을 알 수 있습니다.

그렇다면, 파일을 출력하는 과정에서 field3와 field4가 출력되지 않았다고 예상됩니다.

 


 

가장 먼저 field 4는 transient 키워드가 붙어있기 때문에 애초에 출력이 되지 않습니다.

field3를 출력하지 못하는 이유는 메모리 영역에서 알 수 있습니다.

 

객체의 정보(필드)는 힙 메모리 영역에 저장되는 반면 정적 필드는 static 영역에 저장됩니다.

 

즉, 객체 입출력 스트림은 객체의 정보(필드)를 출력하고 읽는 스트림인데,

일반 필드가 저장되어 있는 힙 영역정적 필드가 저장되는 static 영역은 완전히 별개의 영역이기 때문에 입력받지 못하는 것입니다.

 

 


 

마지막으로 간단한 예제를 통해 조금 더 심도있게 살펴보겠습니다.

 

 

Parent

 

@ToString
@NoArgsConstructor
public class Parent {
    // Getter, Setter를 사용하지 않고 도트로 접근하기 위해 public
    public String field1;
	
} // end class

 

 

Child

 

@Log4j2
@ToString
@NoArgsConstructor
public class Child
    extends Parent
    implements Serializable {

    private static final long serialVersionUID = 1L;
    public String field2;
	
    // 자바언어표준스펙에서 정의된 메서드를 사용함, 직렬화
    private void writeObject(ObjectOutputStream out) 
            throws IOException {
        log.trace("writeObject({}) invoked.", out);
			
        // 이 메서드 안에서, 확장받은 부모 객체의 필드가 직렬화 가능하도록
        // 상속받은 부모객체의 필드를 직접적으로 출력
        out.writeUTF(field1);
        out.defaultWriteObject();
    } // writeObject
	
    // 역직렬화
    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException {
        log.trace("readObject({}) invoked.", in);
		
        // 이 메서드 안에서, 확장받은 부모 객체의 필드가 역직렬화 가능하도록
        // 상속받은 부모객체의 필드를 직접적으로 입력
        field1 = in.readUTF();
        in.defaultReadObject();
    } // readObject
	
} // end class

 

위 코드에서 serialVersionUID 필드는 만약 클래스가 변경(예를 들어, 필드가 추가되거나 삭제)되면 직렬화된 객체의 형식과 해당 클래스의 형식을 맞추기 위해 사용됩니다.

 

serialVersionUID는 직렬화/역직렬화 과정에서 클래스 버전을 확인하고 만약 serialVersionUID의 값이 동일하다면 필드의 정보 상관없이 역직렬화할 수 있습니다.

 

 

Child 클래스에서 선언된 메서드들은 자바 언어 표준 스펙에서 정의된 메서드를 사용하였습니다.해당 메서드들은 직렬화/역직렬화를 할 때, JVM이 자동으로 콜백(callback)을 합니다. 즉, 이 메서드를 사용함으로써 Serializable하지 못한(직렬화/역직렬화가 불가능한) Parent 클래스의 객체 정보도 직렬화/역직렬화를 가능하게 만듭니다.

 

 

다음은 실행 클래스 입니다.

 

@Log4j2
public class NonSerializableParentExample {

	
    public static void main(String[] args) throws Exception{
		
        @Cleanup FileOutputStream fos = new FileOutputStream("C:/Temp/Object.dat");
        @Cleanup ObjectOutputStream oos = new ObjectOutputStream(fos);
		
        // 필드 초기화
        Child child = new Child();
        child.field1 = "홍길동";
        child.field2 = "홍삼원";
        // 부모가 serializable하지 않아도 직렬화 가능함
        oos.writeObject(child);
		
		
		
        oos.flush();
		
        log.info("write done.\n");
		
        // ===================================================
		
        @Cleanup FileInputStream fis = new FileInputStream("C:/Temp/Object.dat");
        @Cleanup ObjectInputStream ois = new ObjectInputStream(fis);
		
        Child childObj = (Child) ois.readObject();
		
        // Serializable하지 않은 Parent Class의 필드 정보는 역직렬화 불가능함
        log.info("1.field1: {}", childObj.field1);
        log.info("2.field2: {}", childObj.field2);
		
    } // main
	
} // end class

 

입출력을 하나의 클래스에서 구현하였습니다.

 

다음은 코드 결과입니다.

 

Child 클래스에서 메서드를 선언했을 때, 결과

 

보시는 것처럼, JVM은 Parent 클래스가 직렬화/역직렬화가 불가능하다는 것을 알고 Child 클래스의 메서드를 자동으로 콜백하였습니다. 

 

만약 Child 클래스에 해당 메서드가 없다면 어떻게 될까요?

 

Child 클래스에서 메서드 주석처리

 

콘솔 결과에서도 알 수 있듯이, Parent 클래스에 속한 field1 필드가 null값으로 입력된 것을 확인할 수 있습니다.

즉, JVM이 직렬화/역직렬화가 불가능한 클래스를 발견하고 콜백할 메서드를 찾지 못하면 직렬화/역직렬화를 못한 상태로 입/출력이 이루어지게 됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

'Java' 카테고리의 다른 글

레코드  (0) 2023.09.06
보조 스트림  (0) 2023.08.17
파일 클래스  (0) 2023.08.17
Exception Handling  (0) 2023.07.28
Exception  (0) 2023.07.27

+ Recent posts