프로그램 작성
자바 프로그램을 작성하고, 컴파일러를 이용해 소스 코드를 바이트 코드로 변환합니다. 이 바이트 코드는 JVM에서 실행됩니다.
클래스 로더
JVM은 프로그램을 실행하기 위해 클래스 로더를 이용해 필요한 클래스 파일을 찾습니다. 클래스 로더는 클래스 파일을 찾고, 로딩, 검증, 준비, 그리고 링크하는 작업을 수행합니다.
바이트 코드 검증
JVM은 클래스 파일을 로딩한 후, 바이트 코드 검증 과정을 수행합니다. 이 과정에서는 바이트 코드가 유효하고 안전한지 확인합니다. 만약 검증 과정에서 문제가 발생하면, JVM은 해당 클래스를 실행하지 않고 예외를 발생시킵니다.
실행 엔진
JVM은 검증된 바이트 코드를 실행 엔진을 이용해 실행합니다. 실행 엔진은 바이트 코드를 명령어로 변환하고, 명령어를 실행하는 작업을 수행합니다. 실행 엔진은 인터프리터 방식 또는 JIT(Just-In-Time) 컴파일러 방식으로 동작합니다.
기본형 (Primitive Type)
기본형은 논리형, 정수형, 실수형으로 나눌 수 있습니다.
1-1. 논리형 (boolean)
논리형은 true와 false의 값을 가지며, 논리 연산자와 함께 사용됩니다. 크기는 1 byte 입니다.
1-2. 정수형 (byte, short, int, long)
정수형은 음의 정수, 0, 양의 정수를 모두 포함합니다. 각각의 데이터 타입은 다음과 같은 크기를 가집니다.
1-3. 실수형 (float, double)
실수형은 소수점 이하의 값을 가질 수 있습니다. 각각의 데이터 타입은 다음과 같은 크기를 가집니다.
참조형 (Reference Type)
참조형은 객체, 배열 등을 저장하는 데이터 타입입니다. 참조형은 기본형과 달리 변수에 값이 직접 저장되는 것이 아니라, 객체나 배열이 저장된 메모리 주소값을 참조합니다.
추상 클래스는 하나 이상의 추상 메소드를 포함하고, 일반 메소드도 포함할 수 있는 클래스입니다. 추상 클래스는 객체를 직접 생성할 수 없으며, 이를 상속한 서브 클래스에서 추상 메소드를 오버라이딩하여 구현합니다.
인터페이스는 추상 메소드와 상수만을 가지는 것으로, 다른 클래스나 인터페이스에서 구현될 기능을 정의하는데 사용됩니다. 인터페이스는 구현하는 클래스에서 구현되어야 하는 기능을 명시하고, 이를 통해 객체들이 서로 독립적으로 상호작용할 수 있게 됩니다.
Java에서 상속은 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 상속은 부모 클래스에서 정의된 메소드와 변수를 자식 클래스에서 재사용할 수 있도록 합니다. 자식 클래스는 부모 클래스의 모든 기능을 상속하면서 자신만의 기능을 추가하거나 부모 클래스의 기능을 수정할 수 있습니다. 이를테면, 자식 클래스는 부모 클래스가 제공하는 메소드를 호출할 수 있고, 부모 클래스의 멤버 변수를 사용할 수 있습니다.
다형성은 Java에서 객체 지향 프로그래밍을 구현하는 또 다른 개념입니다. 다형성은 객체의 동일한 메소드가 다양한 방식으로 호출될 수 있도록 합니다. 이것은 다양한 객체 유형이 동일한 메소드를 구현할 수 있도록 하고, 각 객체가 해당 메소드를 다르게 구현하여 다른 동작을 수행할 수 있도록 합니다.
throw: 프로그래머가 직접 예외 객체를 던지는 경우에 사용합니다. 예외 객체를 던져서 호출자에게 예외 처리를 위임할 수 있습니다.
throws: 메소드에서 발생할 수 있는 예외의 종류를 선언하는 경우에 사용합니다. 예외가 발생하면 호출자에게 예외 처리를 위임할 수 있습니다.
결국, "throw"는 직접 예외 객체를 던지는 것이고, "throws"는 메소드에서 발생할 수 있는 예외를 선언하는 것입니다.
제네릭은 클래스나 메소드에서 사용할 데이터 타입을 미리 지정하지 않고, 런타임 시에 동적으로 결정할 수 있도록 하는 기능입니다. 제네릭을 사용하면 클래스나 메소드를 일반화할 수 있어서 코드의 안전성, 재사용성과 유지보수성을 향상시킬 수 있습니다.
데이터를 저장하고 관리하는 자료구조를 표준화하여 제공하는 라이브러리입니다. 컬렉션 프레임워크는 데이터의 저장 방식, 접근 방법, 조작 방법 등을 표준화하여, 다양한 타입의 데이터를 효율적으로 처리할 수 있도록 합니다.
컬렉션 프레임워크는 크게 List, Set, Map 인터페이스로 구성됩니다. 각 인터페이스는 다양한 구현 클래스를 가지며, 이를 사용하여 데이터를 저장하고 조작할 수 있습니다.
Java에서 객체 직렬화(Object Serialization)란, 객체를 바이트 단위로 변환하여 저장하거나 전송할 수 있는 기능을 말합니다. 이를 통해 객체를 파일에 저장하거나 네트워크를 통해 전송하는 등의 기능을 수행할 수 있습니다.
컬렉션, 배열 등의 데이터를 처리하기 위한 함수형 프로그래밍 API입니다. 스트림 API는 데이터를 처리하는 데 있어서 간결하고 가독성이 좋은 코드를 작성할 수 있도록 지원합니다.
유닛 테스트(Unit Test)는 개발자가 작성한 코드의 각각의 기능이 제대로 동작하는지 검증하는 테스트입니다. Java에서는 JUnit과 Mockito를 이용하여 유닛 테스트를 진행할 수 있습니다.
JUnit은 Java에서 가장 널리 사용되는 단위 테스트 프레임워크 중 하나입니다. JUnit을 사용하여 테스트 케이스를 작성하면, 각 테스트 케이스가 독립적으로 실행되어 코드의 특정 기능에 대한 검증이 가능해집니다.
Mockito는 Java에서 가장 널리 사용되는 mocking 프레임워크 중 하나입니다. Mockito를 사용하여 테스트할 때, 실제 객체 대신 가짜 객체(mock)를 사용하여 테스트를 수행할 수 있습니다.