# 자바 표준 스펙과 구현

자바는 표준 스펙과 구현으로 나눌 수 있다.

  • 자바 표준 스펙
    • 자바 기본 설계도 및 문서
    • 표준 스펙을 기반으로 여러 회사에서 실제 동작하는 자바를 직접 구현
    • 표준 스펙은 자바 커뮤니티 프로세스를 통해 관리 (JCP)
  • 자바 구현
    • Amazon Correto: AWS 최적화 자바
    • Oracle Open JDK 등

자바 컴파일러, 실행 라이브러리, 자바 가상머신 (JVM)을 구현해야 한다. 다양한 벤더에서 제공중이다.

사용하는 과정에서 JDK 변경도 가능하다.

# 컴파일과 실행

컴파일 및 실행 과정은 다음과 같다.

  1. 자바 코드를 개발자가 작성
  2. 자바 컴파일러를 통해 컴파일
    1. 자바가 제공하는 javac 프로그램 사용
    2. .java -> .class 파일이 생성
    3. 자바 소스 코드를 바이트코드로 변환하여 자바 가상 머신에서 빠르게 실행될 수 있도록 최적화하고 문법 오류를 검출
  3. 자바 프로그램 실행
    1. 자바가 제공하는 java 프로그램을 사용하여 실행
    2. JVM이 실행되며 프로그램 작동

인텔리제이 IDE를 사용하는 경우 javac를 활용한 컴파일러 동작과 java를 활용한 JVM 위에서의 바이너리 코드 실행 과정을 자동으로 처리해준다.

자바는 자바가 설치된 모든 OS에서 실행될 수 있다. 각 OS별 자바가 OS별로 실행되어야 할 명령어를 맞춰준다.

자바의 운영체제 독립성 덕분에 서버 환경에 자바만 설치해두면 개발 환경과 상관없이 쉽게 배포가 가능하다.

# 패키지 / 변수 선언

패키지는 폴더 개념으로, 해당 패키지에 들어가는 자바 파일 첫줄에 package 패키지명을 선언해줘야 한다.

변수 선언은 아래와 같이 진행한다.

package test_variable;

public class Var1 {
    public static void main(String[] args) {
        int a = 1;

        System.out.println(a);
        System.out.println(a);
    }
}

자바에서 사용되는 여러 타입들

  1. int a = 1;
  2. double b = 2.1;
  3. boolean c = true;
  4. char d = 'A';
  5. String e = "Hello";

# 숫자 타입별 메모리 크기

  1. 정수형
    1. byte: -128 ~ 127 (1byte, 2^8)
    2. short: -32,768 ~ 32,767 (2byte, 2^16)
    3. int: -2,147,483,648 ~ 2,147,483,647 (4byte)
    4. long: 8byte
  2. 실수형
    1. float: 4byte, 7자리 정밀도
    2. double: 8byte, 15자리 정밀도
  3. 기타
    1. boolean: 1byte
    2. char: 2byte
    3. String: 문자 길이에 따라 동적으로 달라짐

:::tips 실무에서 사용하지 않는 타입들

byte, short, float, char는 잘 사용하지 않는다.

:::

자바는 일반적으로 Camel Case로 변수명을 작성한다.
클래스명은 대문자로 시작한다. 패키지명은 모두 소문자로 사용한다.

# 연산자

참고사항만 간단히 정리한다.

  • 문자열 덧셈 가능
  • int끼리 나눗셈 연산은 몫 연산으로 이루어진다. 소숫점 결과를 원하는 경우 형변환이 필요하다.
  • 문자열과 다른 타입의 값에 덧셈 연산을 하는 경우 다른 타입의 값을 문자열로 변환하여 합친 뒤 문자열을 리턴한다.
  • 자바는 증감연산자를 지원한다. ++a;, --a
    • 전위, 후위 모두 지원한다.

# 조건문

  • if문 구조는 다른 언어와 동일하다.
  • switch-case도 동일하다.
    • break를 통해 switch를 빠져나간다. break를 작성하지 않으면 나머지 조건 연산도 수행한다.
  • 값을 리턴하는 switch-case문이 자바 14 이후로 도입되었다.
  • 삼항연산자도 지원한다.
switch(condition) {
    case value1:
        break;
    case value2:
        break;
    default:
}
int result = switch (a) {
    case 1 -> 1000;
    case 2 -> 2000;
    default -> 3000;
};

# 반복문

  • while(conditon) { }
  • do { } while(condition);
  • break, continue 동일
  • for(int i = 1; i <= 10; i++) { }
  • for-each문을 지원한다.
int[] numbers = { 1,2,3,4,5 };

for(int number : numbers) {
    System.out.println(number);
}

# 스코프, 형변환

  • 지역 변수는 코드블록 내에서 생존한다.
    • if, while문같은 구문 내에서 선언된 변수도 지역변수다.
    • 코드블록 종료 시점에 해당 지역변수를 메모리에서 제거한다.
  • 더 큰 범위의 데이터로 대입 연산이 가능하다.
    • int -> double 등
  • 자동 형 변환을 지원한다.
  • intValue = (int) doubleValue; 형태로 명시적 형 변환이 가능하다.
  • 오버플로우 발생 시 시계가 돌듯 해당 타입의 최소값에서 값 계산이 이어서 이루어진다. (오버플로우 발생 자체를 막으면 된다.)

# 입력 받기

  • Scanner 클래스를 활용하면 입력을 받을 수 있다.
    • java.util.Scanner를 임포트한다.
    • 입력 데이터 타입별로 nextInt, nextLine, nextBoolean 등이 존재한다.
  • System.in.read();로 입력을 받을 수 있지만 1바이트 크기 데이터 하나만 입력 가능하다.
    • 입력 시 아스키 코드가 반환되고, 반환된 코드 값을 기반으로 파싱 작업이 추가로 필요하기 때문에 번거롭다.
  • System.out.println();은 출력에 개행을 추가하는 것이고, System.out.print()는 개행을 추가하지 않는다.
import java.util.Scanner;

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("문자열 입력:");
    String str = scanner.nextLine();
    System.out.println(str);
}

# 배열

  • new int[카운트]를 통해 생성한다.
    • 기본값은 0으로 초기화된다.
  • 배열은 참조 타입으로 관리된다.
  • length 프로퍼티로 배열 길이를 알수있다.
  • new int[]{ 1,2,3,4,5 };를 통해 생성과 동시에 초기화가 가능하다. 배열 크기까지 명시하는건 비문이다.
  • int[] numbers = { 1,2,3,4,5 }; 형태로도 초기화 가능하다.
  • int[][] arr = new int[2][3];으로 2차원 배열 생성도 가능하다.
public static void main(String[] args) {
    int[] a = new int[5];
}

# 메서드

  • 함수에 넘기는 실제 값을 인자(Argument, 아규먼트)라고 한다.
  • 메서드 정의 시 선언한 변수를 매개변수 (Parameter)라고 한다.
  • 자바 메서드는 변수의 값을 항상 복사하여 리턴한다.
    • 참조를 리턴하는 경우 참조값을 복사하여 리턴한다.
  • 메서드 오버로딩을 지원한다.
public static void main(String[] args) {
    int result = add(1,2);
    System.out.println(result);
}

public static int add(int a, int b) {
    return a + b;
}