Java Basics (2)

Wonho Kim·2025년 1월 2일

Java Basics

목록 보기
2/6

해당 시리즈의 게시물은 codelatte.io 사이트를 참고하여 정리한 내용입니다.
https://www.codelatte.io/courses/java_programming_basic

5. 형 변환

형 변환은 기존의 자료형에서 다른 자료형으로 변환하는 것을 의미한다.

byte a = 32;

// 1 byte로 저장된 값을 2 byte로 변환
short b = a;

5-1. 암시적 형 변환

암시적 형 변환은 직접 형 변환 접두사를 사용하지 않고 자동적으로 형 변환되는 것을 의미한다.

byte a = 32;

// 1 byte -> 2 byte
short b = a;

// 2 byte -> 4 byte
int c = b;

// 4 byte -> 8 byte
long d = c;
float a = 1.12F;

// 단정도(4 byte)로 저장된 부동소수점을 배정도(8 byte)로 변환
double b = a;

여기서 주의해야 할 점은 자료형의 메모리 공간 크기를 기준으로 변환하지 않고 값의 표현 범위를 기준으로 변환한다.

5-2. 명시적 형 변환

명시적 형 변환은 데이터 손실이 발생할 수 있다는 것을 인지하고 형 변환을 한다고 명시하는 것을 의미한다. 예를 들어 8 byte로 표현되는 1000억의 리터럴 값이 4 byte로 표현하려고 하면 데이터 변질이 발생할 수 밖에 없다.

명시적 형 변환 구문

[자료형] [변수명] = (자료형) [변수명 또는 리터럴];
int a = (int) 100000000000L;

long b = 1000;
int a = (int) b;

정수의 명시적 형 변환

long a = 100000;

// 8 byte로 저장된 값을 4 byte로 변환
// 다만 100000은 4 byte로 표현이 가능하기 때문에 손실이 없음
int b = (int) a;

// 4 byte로 저장된 값을 2 byte로 변환
// 다만 100000은 2 byte로 표현할 수 없기 때문에 데이터 손실 및 변질
short c = (short) b;

실수의 명시적 형 변환

double a = 1.42;

// 배정도(8byte)로 저장된 부동소수점을 단정도(4 byte)로 변환
float b = (float)a;

정수에서 실수로 명시적 형 변환

float a = 32.123F;

// 단정도(4 byte) 부동소수점을 정수로 변환
int b = (int)a;

// 변수 b에 실제로 저장된 값 : 32

정수에서 실수로 명시적 형 변환(변질)

float a = 10000000000.0F;

// 단정도(4 byte) 부동소수점을 정수로 변환
int b = (int)a;

// 변수 b에 실제로 저장된 값 : 2147483647

a 변수는 int로 표현할 수 있는 정수의 값의 범위를 넘었기 때문에 표현 가능한 최대값인 2147483647를 저장하게 된다. 이와 같이 데이터가 변질될 가능성을 염두해 두어야 한다.

5-3. 연산시 형 변환

정수형끼리 산술 연산은 4 byte 정수형으로 암시적 형 변환이 일어난다.

정수와 실수의 산술 연산은 실수형으로 암시적 형 변환이 일어난다. 실수의 값의 표현 범위가 더 넓기 때문이다.

6. 배열

변수를 상자에 비유한다면 배열은 상자들의 모음이며, 인덱스는 특정 상자에 접근하기 위해 순서대로 부여한 번호이다.

int[] intArray = {1, 2, 3, 4};

아래와 같이 인덱스를 통해 배열에 접근하여 출력이 가능하다.

System.out.println(intArray[0]); // 1
System.out.println(intArray[1]); // 2
System.out.println(intArray[2]); // 3
System.out.println(intArray[3]); // 4

배열을 만드는 방법에는 총 3가지 방법이 있다.

// 1. 공간과 값을 할당하는 방식
int[] intArray = {1, 2, 3, 4};

// 2. 공간과 값을 할당하는 방식
// intArray 선언한 후, 추후에 값을 넣는게 가능
int[] intArray = new int[] {1, 2, 3, 4};

// 3. 공간만 할당한 후, 이후에 값을 넣는 방식
int[] intArray = new int[4];

// 공간만 할당 후 이후에 값을 저장
intArray[0] = 1;
intArray[1] = 2;
intArray[2] = 3;
intArray[3] = 4;

배열을 선언하게 되면 정수 자료형은 0, 실수 자료형은 0.0, 문자열은 null로 초기화되어있다.

int[] intArray = new int[4];

intArray[0] = 1;
intArray[2] = 3;
intArray[3] = 4;

System.out.println(intArray[0]); // 1
System.out.println(intArray[1]); // 0
System.out.println(intArray[2]); // 3
System.out.println(intArray[3]); // 4
String[] textArray = new String[4];

textArray[0] = "안녕1";
textArray[2] = "안녕2";
textArray[3] = "안녕3";

System.out.println(textArray[0]); // 안녕1
System.out.println(textArray[1]); // null
System.out.println(textArray[2]); // 안녕2
System.out.println(textArray[3]); // 안녕3

6-1. 2차원 배열

2차원 배열의 경우 엑셀의 row x column이나 행렬개념을 생각하면 된다.

2차원 배열의 선언은 아래와 같다.

char[][] page = new char[상위 차원의 크기][하위 차원의 크기];

2차원 배열을 만드는 방법 역시 3가지가 있다.

// 1. 공간과 값을 할당하는 방식
char[][] page = { 
        {'1', 'p', 'a', 'g', 'e'},
        {'오', '늘', '은', '뭐', '할'},
        {'까', '공', '부', '하', '자'}
};

// 2. 공간과 값을 할당하는 방법
char[][] page = new char[][] { 
        {'1', 'p', 'a', 'g', 'e'},
        {'오', '늘', '은', '뭐', '할'},
        {'까', '공', '부', '하', '자'}
};

// 3. 공간만 할당 후 이후에 값을 넣는 방법
char[][] page = new char[3][5]; 

page[0][0] = '1'; 
page[0][1] = 'p';
page[0][2] = 'a';
page[0][3] = 'g';
page[0][4] = 'e';

page[1][0] = '오';
page[1][1] = '늘';
page[1][2] = '은';
page[1][3] = '뭐';
page[1][4] = '할';


page[2][0] = '까';
page[2][1] = '공';
page[2][2] = '부';
page[2][3] = '하';
page[2][4] = '자';

6-2. 3차원 배열

사실 3차원부터 잘 사용하진 않지만, 그래도 개념은 2차원과 동일하니 크게 걱정할 필요가 없다.

char[][][] page = new char[최상위 차원의 크기][상위 차원의 크기][하위 차원의 크기];
char[][][] page = { 
    {
        {'1', 'p', 'a', 'g', 'e'},
        {'오', '늘', '은', '뭐', '할'},
        {'까', '공', '부', '하', '자'}
    },
    {
        {'2', 'p', 'a', 'g', 'e'},
        {'그', '냥', '놀', '자', '내'},
        {'일', '도', '잘', '놀', '자'}
    }
};

7. 연산자

7-1. '+', '-', '*', '/'

수학 개념에서 사용하는 기본 사칙연산인 덧셈, 뺄셈, 곱셈, 나눗셈은 다음과 같은 연산자를 사용한다.

int num = 100;
int[] boxArr = {10, 20, 30, 50};

// 덧셈: 110
int add = num + boxArr[0];

// 뺄셈: 80
int add = num - boxArr[1];

// 곱셈: 3000
int add = num * boxArr[2];

// 나눗셈: 2
int add = num / boxArr[3];

※ '%'

'%'는 나머지 연산자이며 나눈 결과의 나머지를 반환하는 연산이다.

int num = 100;

// 나머지가 0이므로 result에 0 저장
int result = num % 10;

7-2.'++'과 '--' 연산

'++'과 '--' 연산은 선행후행이 있는데 연산을 진행하고 값을 반환할지, 아니면 값을 먼저 반환한 다음 연산을 진행할지에 대한 순서의 차이가 존재한다.

'++'는 1을 증가시키는 연산, '--'는 1을 감소시키는 연산을 수행한다.

처음보면 그게 무슨차이냐 할수도 있지만 예시 코드를 보면 차이점을 파악할 수 있다.

int add_first = 100;
int add_last = 100;

int sub_first = 100;
int sub_last = 100;

// 100에서 1을 더한 후 해당 값을 반환하여 출력
// add_first 값은 101이 된 상태로 출력
System.out.println(++add_first);

// add_last인 100을 먼저 반환하여 출력한 후 값을 1 증가시킴
System.out.println(add_last++);
// 여기 주석이 적힌 시점에서부터 add_last 값은 이제 101이 됨

// 100에서 1을 뺀 후 해당 값을 반환하여 출력
// sub_first 값은 99가 된 상태로 출력
System.out.println(--sub_first);

// sub_last인 100을 먼저 반환하여 출력한 후 값을 1 감소시킴
System.out.println(sub_last--);
// 여기 주석이 적힌 시점에서부터 sub_last 값은 이제 99가 됨

7-3. '<', '>', '<=', '>=', '==', '!='

'<', '>', '<=', '>=', '==', '!='은 모두 비교연산자이며 각각 '크다', '작다', '크거나 같다', '작거나 같다', '같다', '같지 않다'의 비교연산을 진행한다.

int num = 100;

boolean big = num > 90; //true
boolean small = num < 90; // false
boolean big_eq = num >= 100; //true
boolean smal_eq = num <= 99 // false
boolean eq = num == 90; // false
boolean not_eq = num != 90; // true

7-4. '&&', '||', '!'

컴퓨터나 전자과 학생이면 모를 수 없는 디지털논리회로에서 AND, OR, NOT 연산을 진행해주는 연산기호이다.

int num = 100;

// false
boolean result1 = (10 < 100) && (10 < 1);

// true
boolean result2 = (10 < 100) || (10 < 1);

// false
boolean result3 = !(10 < num);

8. 조건문

8-1. if

가장 위에 있는 조건식부터 순차적으로 확인하며 'true'인 조건식을 만나면 조건문 내부에 있는 코드를 실행한 후 조건문을 탈출한다.

if (참 or 거짓) {
    // 참이면 실행 후 조건문 탈출
} else if (참 or 거짓) {
    // 참이면 실행 후 조건문 탈출
} else if (참 or 거짓) { 
    // 참이면 실행 후 조건문 탈출
} else {
   // 세 조건이 다 거짓이면 실행 후 탈출
}
int num = 65;
char alphabet;

if (65 == num) {
    alphabet = 'A';
} else if (66 == num) {
    alphabet = 'B';
} else if (67 == num) {
    alphabet = 'C';
} else {
    alphabet = '0';
}

System.out.println(alphabet);
// A

8-2. switch

switch는 조건값에 따라 특정 case부터 실행할 수 있도록 하는 구문이다. 적합한 case부터 아래로 쭉 실행하면 break 키워드를 만나면 switch문을 탈출한다.

int category = 1;
switch (category) {
    case 1:
        System.out.println(1);
    case 2:
        System.out.println(2);
            break;
    case 3:
        System.out.println(3);
}

// 1
// 2

만약 switch를 if문 처럼 사용하고 싶다면 (조건식 내부에 있는 코드를 실행한 후 다른 조건식을 고려하지 않는 구조) 반드시 모든 case에 break문을 까먹지 말고 붙이는 것이 좋다.

위 코드도 처음에는 case 1을 만나 1을 출력하였으나 break 문이 없어 case 2까지 출력하게 된 것이다.

8-3. 삼항연산자

삼항 연산자는 if 문을 만들 수 있는 또 다른 방법을 제공한다.

자료형 변수명 = (조건식) ? 참인 경우 : 거짓인 경우;
int num = 65;
char alphabet = (65 == num) ? 'A' : 'B';

// 여기서는 참이므로 'A'가 반환되어 저장됨

9. 반복문

어떤 일을 반복적으로 실행해야할 경우 반복문을 이용하여 명령어를 반복적으로 실행할 수 있다.

9-1. for

for는 대체로 반복할 횟수가 정해져 있을 때 사용한다.

for (초기화 ; 조건식; 반복 후 실행될 명령어) {
    // 반복 시킬 내용
}
for (int num = 0; num < 4; num++) {
    System.out.println(num);
}

// 0
// 1
// 2
// 3

9-2. while

while은 대체로 반복할 횟수가 정해져 있지 않을 때 사용한다.

while (조건식) {
    // 반복 시킬 내용
}
int num = 0;
while (num < 4) {
    num++;
    System.out.println(num);
}

// 1
// 2
// 3
// 4

9-3. do while

조건 여부 상관 없이 먼저 실행할 코드가 필요한 경우 사용한다.

do {
    // 반복 시킬 내용
} while(조건식);
int num = 0;
do {
    num++;
    System.out.println(num);
} while (num < 4);

9-4. foreach

foreach 반복문은 배열이나 이터레이터를 상속받은 자료구조에서 원소를 순차적으로 접근할 때 사용한다.

for (변수 : 배열 or 이터레이터) {
    // 반복 시킬 내용
}
int[] numArray = {10, 20, 30, 40};

for (int num : numArray) {
    System.out.println(num);
}

// 10
// 20
// 30
// 40

※ break, continue

반복문은 아니지만 거의 항상 같이 사용하는 break, continue 키워드가 있다.

break 키워드를 만나게 되면 반복문은 종료되고 가장 가까운 반복문을 탈출한다.

int i = 0;

while (true) {
	i++;
    if (i > 100) {
    	break;
    }
}

continue 키워드를 만나게 되면 조건식으로 다시 올라가 조건 체크 후 조건식이 참이면 반복문 내부 코드를 실행한다.

int i = 0;

while (i < 100) {
	i++;
    if (i % 2 == 0) {
    	continue;
    }
    System.out.println(i);
}

위 코드에서는 i를 2로 나머지셈한 결과가 0이면 출력문을 수행하지 않고 다시 조건식으로 올라가게 된다.

이러한 특징을 잘 살려서 특정 상황에서만 반복문이 탈출되도록 설계할 수 있다.

profile
새싹 백엔드 개발자

0개의 댓글