코어 자바9 (1), 기본 프로그래밍 구조

2022. 6. 29. 23:17자바

728x90
반응형

본 포스팅은 '가장 빨리 만나는 코어 자바9' 책을 기준으로 중요한 내용을 정리합니다. 

자바 언어는 C++과 유사한 점이 많기에 유사한 점을 제외하고 다른 점을 위주로 작성하고자 합니다.

7월 중순 이내로 책을 모두 읽고 정리하는 것을 목표로 잡습니다. 


1. Hello world

1) 자바 프로그램 컴파일 및 실행

javac ch01/sec01/HelloWorld.java
java ch01.sec01.HelloWorld

- 첫번째 줄은 바이트 코드로 컴파일 후 클래스 파일에 저장하는 명령어이다. 바이트 코드는 한번 컴파일하면 모든 자바 가상 머신에서 실행할 수 있다. 

- 두번째 줄은 java 명령으로 가상 머신을 구동하고 클래스 파일을 로드해서 바이트 코드를 실행한다.

 

2) 메서드 호출

- 메서드 호출은 객체 지향 언어의 방식을 그대로 따른다. 객체.메소드()의 방식으로 실행하고, ()에 인자를 전달하면 된다.

 

2. 기본 타입

1) 부호가 있는 정수타입

타입 저장 공간 범위
byte 1바이트 -128~127
short 2바이트 -32,768~32,767
int 4바이트 -2,147,483,648~2,147,483,647
long 8바이트 -2의 64승 ~ 2의 64승 - 1

- long 타입으로 충분하지 않는다면 BigInteger를 사용한다.

 

2) 부동 소수점 타입

타입 저장 공간 범위
float 4바이트 유효자릿수 6~7
double 8바이트 유효자릿수 15

 

3) char 타입

UTF-16 문자 인코딩의 코드 유닛을 나타낸다.

 

4) boolean 타입

- false와 true 두 개 뿐이고, 자바에서 boolean은 숫자 타입이 아니어서 정수 0과 1은 관련 없다.


3. 변수

1) 변수 선언

- 선언과 정의가 다르게 명시될 수 있다.

- 자바에서는 낙타 표기법을 주로 사용한다.

- 자바에서 변수 선언은 최대한 미루는 것이 좋은 방식으로 여겨진다.

- 초기화되지 않은 변수를 사용할 때 에러가 발생한다.

- 변수명은 문자로 시작해야하며 _와 $ 기호, 숫자, 문자로 구성될 수 있다. 단, $는 자동으로 생성되는 이름용이므로 사용하지 않는 것이 좋다.

 

2) 상수

- 상수 이름은 대문자로 선언하는 관례를 따른다.

- final을 사용해 정의한다.

final int DAYS_IN_FEBRUARY;
if (leapYear){
	DAYS_IN_FEBRUARY = 29;
} else {
	DAYS_IN_FEBRUARY = 28;
}

- C++과는 다르게 상수의 선언과 초기화를 다르게 해줄 수 있다. 단, 한번 초기화를 한 뒤에는 값을 바꿀 수 없다.


4. 산술 연산

- 자바에서는 객체에 연산자로 연산자를 사용 할 수 없다. 따라서 메소드를 사용해 연산을 해야한다.

- 오버플로우가 가능하기에 Exact가 붙은 함수를 사용하면 예외를 잡아낼 수 있다.


5. 문자열

1) 문자열 연결

- 문자열간의 결합은 + 연산자를 사용한다. 정수형을 더할 경우에는 문자열의 결합처럼 동작한다.

String location = "Java";
System.out.println(location + 1111);

 

2) 부분 문자열

- substring을 사용한다. 이때 파라미터로 범위를 지정하는데, 파이썬에서와 동일하다.

String greeting = "Hello, World!";
String location = greeting.substring(7, 12) // location을 "World"로 설정한다.

 

3) 문자열 비교

- equals를 사용한다. == 연산자는 동일한 객체인지 검사하는 것이기에 이를 사용하면 안된다.

- 문자열에 null을 할당해줄 경우에는 빈문자열과는 다른 어떤 문자열도 참조하지 않는 것을 의미한다. 이때 ==를 통해 비교할 수 있다.

"World.equals(location)";

- 리터럴을 앞쪽에 두면 location이 null일 때도 동작한다.

- 대소문자를 구별하지 않는다면 equalsIgnoreCase를 사용한다.

 

"World".equalsIgnoreCase(location);

- compareTo는 앞에 객체가 인자로 전달된 값보다 앞에오면 음의 정수를, 뒤에 오면 양의 정수를, 같으면 0을 반환한다.

 

4) 숫자와 문자열 사이의 변환

- toString을 사용하면 된다.

int n = 42;
String str = Integer.toString(n);
System.out.println(str); // 42

String str2 = Integer.toString(n, 2);
System.out.println(str2); // 101010

- toString은 기수를 설정해줄 수 있다.

- 다른 언어와 마찬가지로 문자열은 immutable하다.

 

5) 코드 포인트와 코드 유닛

- 자바는 유니코드 표준을 수용했다. 현재 유니코드는 21비트인데, 유효한 유니코드 값을 코드 포인트라 한다. 

- UTF-16은 길이가 가변적이고 하위 호환성을 지원하는 인코딩을 의미한다. 

 


6. 입력과 출력

1) 입력 읽어오기

// input
// Scanner
import java.util.Scanner;

Scanner in = new Scanner(System.in);
String line = in.nextLine(); // 한줄 입력
String firstName = in.next(); // 공백으로 구분된 단어
int age = in.nextInt(); // 정수 입력
in.hasNextInt(); // 다음 정수가 있는지 검사

- Scanner를 사용해 입력을 읽어올 수 있다. 단, 이는 터미널에서 내용이 보이므로 비밀번호를 읽을 때는 사용하면 안된다. 이땐 Console 클래스를 사용할 수 있다.

- 포맷 문자열은 파이썬과 동일하다. 


7. 제어 흐름

1) 분기와 루프, break, continue

- C++과 거의 유사하다.  if, switch, for, while문을 사용하는 방식이 동일하다. 이와 더불어 break, continue ㄸ한 사용 방식이 동일하다.

- 레이블을 붙은 break 문이 있다. 이는 컴퓨터 구조에서의 분기에서 레이블로 이동하는 것과 비슷하다고 생각하면 된다.

- 반복문 이전에 변수를 선언한 뒤, 그 변수를 활용해 반복문을 돌린다면 반복문이 끝나더라도 변수를 사용할 수 있지만 변수를 선언하지 않은 뒤에 반복문에서 사용했던 변수를 사용한다면 사용할 수 없다.

for (int i = 0; i < n; i++) { // i가 검사 및 업데이트의 유효 범위 안에 있다.
	...
}
// 여기서는 i가 정의되어있지 않다.

int i;
for (int i = 0; i < n; i++) { // i가 검사 및 업데이트의 유효 범위 안에 있다.
	...
}
// 여전히 i를 사용할 수 있다.

- 자바는 서로 겹치는 유효 범위에 이름이 같은 지역변수를 여러 개 둘 수 없다.

 


8. 배열과 배열 리스트

1) 배열 다루기

// int[] 정수의 배열
// String[] String의 배열
String[] names2 = new String[100];
int[] primes = {2, 3, 5};

- 배열 또한 C++와 유사하다.

- 한번 생성한 뒤 길이를 변경할 수 없다. 따라서 이를 변경하기 위해 ArrayList를 사용할 수 있다.

- 배열은 요소에 접근하기 위해 [] 연산자를 사용한다.

 

2) 배열 리스트

- 배열 리스트는 제너럴 클래스이기에 <>을 사용해 타입을 지정해야한다.

// ArrayList
import java.util.ArrayList;
ArrayList<String> friends; // friends = new ArrayList<>();

// 값 초기화
import java.util.List;
ArrayList<String> friends2 = new ArrayList<>(List.of("Peter", "Paul"));

- add를 사용해 값을 추가한다.

- remove를 사용해 값을 제거한다.

- set을 통해 값을 변경한다.

 

3) Wrapper class

- 제너릭 클래스는 기본 타입을 타입 매개변수로 사용할 수 없기에 wrapper class를 사용한다. 

ex) ArrayList<int> (x)         ArrayList<Integer> (o)

- 기본 타입과 그에 대응하는 래퍼 타입의 변환은 자동으로 이뤄진다. 

 

4) 배열과 배열리스트 복사

- 다른 객체지향언어와 마찬가지로 컬렉션 타입에 대해 = 연산자를 사용해 값을 할당하게되면 같은 객체를 참조하게 된다. 이때 복자를 위해선 Arrays.copyof를 사용한다.

 

5) 알고리즘

- sort, fill, reverse, shuffle 등을 사용할 수 있다.

import java.util.Arrays;
import java.util.Collections;

// 값 채우기
int[] numbers = new int[10];
Arrays.fill(numbers, 0); // int[] 배열
Collections.fill(friends2, ""); // ArrayList<String>  

// sort
Arrays.sort(numbers);
Collections.sort(friends2);

System.out.println(Arrays.toString(numbers));

 


9. 기능적 분해

1) 정적 메서드 선언 및 호출

- 클래스 내에서 여러 메서드로 나누는 경우 static 제어자로 선언해야한다.

 

2) 가변 인수

- 타입 뒤에 ...을 붙여서 가변 인수 매개변수를 설정할 수 있다.

// 가변 인수
public static double average(double... values) {
    double sum = 0;
    for (double v: values) sum += v;
    return values.length == 0 ? 0 : sum / values.length;
}

- 이러한 가변인수는 가장 마지막에 정의해야한다. (like 디폴트 파라미터)

728x90
반응형