[Java] 자바 기본

N’oublie pas de t’aimer·2025년 1월 2일

Java

목록 보기
1/18
post-thumbnail

자바의 특징

  • 자동 메모리 관리:
    가비지 컬렉터가 사용되지 않는 메모리를 반환해주어 사람이 직접 메모리 관리를 해주지 않아도 되기 때문에 메모리 부족 현상이 적다.
  • 멀티 쓰레드:
    하나의 프로그램에서 여러 작업을 동시에 할 수 있다.
  • 풍부한 라이브러리:
    개발을 쉽게 만들어줌
  • 운영체제에 독립적:
    한 운영체제에서 만들어진 자바 프로그램을 다른 운영체제에서도 프로그램 수정 없이 실행할 수 있다
  • 객체지향 언어:
    재사용성과 유지보수성이 좋다

자바의 단점

  • 느린 JVM 로딩 속도:
    자바 프로그램은 실행하는 과정에서 Java Virtual Machine이라는 가상 컴퓨터가 반드시 완벽하게 로딩되어야 하기 때문에 프로그램의 초기 시작 시간이 완전한 이진 코드로 컴파일된 프로그램을 실행하는 것에 비해 오래 걸린다.
    하지만 고사양 컴퓨터에서는 아주 많은 라이브러리를 끌어오는 것이 아니라면 체감상 차이는 크게 나지 않는다. 또한 Java 9부터는 런타임 라이브러리를 모듈화하고 있으므로, 필요한 모듈만 끌어서 프로그램을 짤 수 있다.
  • 가비지 컬렉션에 의한 실행 지연:
    가비지 컬렉션에 의한 메모리 프리징 현상으로 인해 프로그램이 순간적으로 뚝뚝 끊기는 듯한 현상이 발생하기도 한다.

자바의 실행과정

확장자가 .java인 소스코드 파일을 javac 라는 컴파일러를 통해 컴파일하여 확장자가 .class인 파일로 변환하여 자바 인터프리터를 통해 실행한다. 클래스는 자바 프로그램의 기본 단위로, 모든 문장은 클래스 안에 있어야 하고, main 메서드는 자바 프로그램의 시작점이다. 이 메서드 없이는 실행이 불가능하다. 객체는 heap에 저장되기 때문에 객체 할당 연산이 실행되는 순간 메모리가 할당이 되고 프로그램 실행 직후에는 어떠한 객체도 존재하지 않는다. 따라서 만약 main 메서드에 static이 붙지 않는다면 런타임 시작 시점에 메서드를 실행할 객체가 없어서 메서드 실행이 불가능하다. 따라서 static을 사용하여 객체의 생성 없이 메서드를 호출 가능하도록 하게 한 것이다.

자바 Bytecode

자바 가상 머신이 이해할 수 있는 언어로 변환된 자바 소스 코드를 의미한다.
자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불린다.
확장자는 .class 이다.
자바 바이트 코드는 자바 가상 머신만 설치되어 있으면, 어떤 운영체제에서라도 실행될 수 있다.

인터프리터 vs JIT 컴파일


개발자가 자바 소스코드(.java)를 작성한다.

자바 컴파일러가 자바 소스코드(.java)파일을 읽어 바이트코드(.class)코드로 컴파일 한다. 바이트코드(.class)파일은아직 컴퓨터가 읽을 수 없는 JVM(자바 가상 머신)이 읽을 수 있는 코드이다. (java - > class)

컴파일된 바이트코드(.class)를 JVM의 클래스로더(Class Loader)에게 전달한다.

클래스 로더는 동적로딩(Dynamic Loading)을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(Runtime Data Area의 Method Area), 즉 JVM의 메모리에 올린다.

실행엔진(Execution Engine)은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행한다. 이 때 실행 엔진은 두 가지 방식으로 변경한다.

  1. 인터프리터 : 바이트 코드 명령어를 하나씩 읽어서 해석하고 실행한다. 하나하나의 실행은 빠르나, 전체적인 실행 속도가 느리다.

  2. JIT컴파일러 : 인터프리터의 단점을 보완하기 위해 도입된 방식으로 바이트 코드 전체를 컴파일하여 바이너리 코드로 변경하고 이후에는 해당 코드를 더이상 인터프리팅 하지 않고, 바이너리 코드를 직접 실행한다. 하나씩 인터프리팅하여 실행하는 것이 아니라 바이트 코드 전체가 컴파일된 바이너리 코드를 실행하는 것이기 때문에 전체적인 실행속도는 인터프리팅 방식보다 빠르다.

자바 버전과 특징

Java 17:
스프링부트 3과 호환되는 최소 자바 버전이 17임

자바 8, 11, 17 버전의 특징

자바 8, 11, 17은 모두 LTS(Long Term Support) 버전으로 장기간의 지원을 받는다.

자바 8

  • 람다 표현식 도입:
    함수형 프로그래밍을 지원하며, 코드를 더 간결하게 작성할 수 있게 되었다.
  • Stream API 추가:
    원본을 변경하지 않고 내부 반복을 통해 코드를 간결하게 작성할 수 있다.
  • default 메소드 추가:
    인터페이스 내에 정의된 default 메소드는 구현까지 포함할 수 있다.

자바 11

  • 람다 지역 변수 정의 시 var 키워드 추가
  • 최신 Http 표준 클라이언트를 구현하는 HttpClient API 제공

자바 17

  • 봉인 클래스 추가:
    해당 클래스를 상속하거나 구현할 클래스를 지정하여 제한한다.
  • 레코드 클래스:
    불변 객체가 되기 위해 필요한 코드를 컴파일 시에 추가해줌

JDK와 JRE

  • JDK:
    Java Development Kit로, JRE와 컴파일러 등 자바 프로그램을 생성하고 컴파일 할 수 있는 기능을 갖춘 키트이다.
  • JRE:
    Java Runtime Environment로, JVM과 라이브러리 클래스, 컴파일된 자바 프로그램을 실행하는 데 필요한 모든 것을 제공한다.

동일성과 동등성

동일성과 동등성은 객체 비교의 개념이다.

  • 동일성:
    실제 객체가 같은 것을 말한다. 두 객체가 가지고 있는 값 뿐만 아니라 힙 메모리 상에서 같은 주소에 위치한다. 물리적인 개념.
    참조 변수를 == 연산자를 사용하여 비교하여 두 참조 변수가 정확히 같은 객체를 가리키는지 확인할 수 있다.
    또한 동일한 객체는 같은 해시코드 값을 가진다.
    해시 코드 값이란 모든 객체가 가지고 있는 고유한 값으로, 보통 객체가 위치한 메모리 주소에 해시 함수를 적용한 결과값을 나타낸다. Object 클래스의 멤버 메소드인 hashCode() 로 해시코드 값을 얻을 수 있다. 두 객체의 해시 코드 값을 비교했을 때 같다면 두 객체는 동일성이 같은 객체이다.
  • 동등성:
    객체가 가지고 있는 값이 같다는 것을 말한다. 논리적인 개념. 즉 객체의 멤버 필드가 가리키는 값이 서로 같다는 것을 의미한다.
    Object 클래스의 equals() 메소드를 오버라이딩 하여 개발자가 동등성 비교 기준을 정의할 수 있다. 오버라이딩 하지 않으면 default로 동일성을 비교하게 된다.

equals()외에 hashCode()도 재정의해야 하는 이유

equals()는 본래 동일성 비교를 위해 사용되는 것인데 동등성 비교를 하기 위해서는 객체의 필드값이 같은지 비교하기 위해 오버라이딩을 통해 재정의해야 한다. 하지만 hashCode()는 보통 객체가 위치한 메모리 주소에 해시 함수를 적용한 결과값이므로 동등한 객체라고 해도 hashCode()값은 서로 다를 수 있다. 따라서 hashCode()도 재정의하여 필드값이 같으면 같은 해시코드 값을 갖도록 재정의해야 동등성 비교에 사용할 수 있다.

toString()

Object 클래스의 멤버 메소드로 객체의 문자열 표현을 반환하는 메서드이다.
형식: 클래스이름@객체 해시코드의 16진수 값
오버라이딩을 통해 재정의를 할 수 있다.

상수와 리터럴

상수는 한 번만 값을 저장할 수 있는 공간이고, 리터럴은 그 자체로 값을 의미한다.

변수의 타입

자바 변수는 기본형 혹은 참조형이다. 기본형은 자바에 정의되어 있는 8가지 문자, 숫자, 논리형 데이터형을 말하고, 기본형이 아닌 모든 데이터형은 참조형에 속한다. 참조형은 사용자가 직접 추가할 수 있으며, 변수에 객체의 메모리 주소를 저장한다.

Call by Value vs. Call by Reference

자바의 매개변수 전달 방식은 Call by Value밖에 없다.
다만 기본형 타입은 값을 복사해서 넘겨주고, 참조형 타입은 참조값을 복사해서 넘겨준다.

직렬화

자바 직렬화란 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술을 아울러서 이야기 한다.
JVM의 메모리에 저장된 객체 데이터를 꺼내서 바이트 형태로 변환하여 다른 프로세스와 통신하거나 외부 저장 매체(데이터베이스나 파일)로 저장하는 것이다.
자바의 기본형과 Serializable 인터페이스를 상속받은 객체는 직렬화할 수 있다.

profile
매일 1퍼센트씩 나아지기 ୧(﹒︠ ̫ ̫̊ ̫﹒︡)୨

0개의 댓글