자바의 세계로 들어가기 전에 반드시 알아야 할 필수 문법입니다.
1️⃣ 타입
자바는 데이터를 저장할 때 타입을 반드시 선언합니다. 타입은 데이터의 종류를 정의하며, 변수에 저장할 수 있는 값의 형태를 제한합니다.
타입 변수 = 값;
boolean flag = true;
int year = 2024;
int month = 5;
double pi = 3.141592653;
char c = 'H';
char c2 = 65; // A 출력
String str = "Hello";
1. 기본 타입
값의 분류 | 기본 타입 |
정수 | byte, char, short, int, long |
실수 | float, double |
논리 (true/false) | boolean |
기본 타입은 값을 직접 저장하는 타입입니다. 정수, 실수, 논리값, 문자를 저장할 수 있습니다.
(*`char`은 문자를 표현하는 데 사용되지만 정수형 데이터로 처리, 각 문자는 유니코드 값으로 매핑된다)
구분 | 타입 종류 | 선언 방법 | 저장 범위 | 메모리 크기 |
|
정수 | byte | byte b = 100; | -128 ~ 127 | 1byte | 8bit |
char | char c = 'A'; | \u0000 ~ \uffff (유니코드) | 2byte | 16bit | |
short | short s = 100; | -32,768 ~ 32,767 | 2byte | 16bit | |
int | int i = 100; | -2,147,483,648 ~ 2,147,483,647 | 4byte | 32bit | |
long | long l1 = 100L; long l2 = 200L; |
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 * 값 뒤에 L 또는 l을 붙일 수 있지만, 소문자 l은 숫자 1과 혼동될 수 있으므로 대문자 L을 권장한다 |
8byte | 64bit | |
실수 | float | float f1 = 10.234F; float f2 = 10.234f; |
1.4 x 10^-45 ~ 3.4 x 10^38 *유효 소수 이하 자리는 약 7자리, 값 뒤에 F 또는 f를 붙인다 |
4byte | 32bit |
double | double d = 10.211; | 4.9 x 10^-324 ~ 1.8 x 10^308 *유효 소수 이하 자리는 약 15자리 |
8byte | 64bit | |
논리 | boolean | boolean flag = true; | 참이면 true, 거짓이면 false |
2. 참조 타입
객체의 번지를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스 타입이 존재합니다.
💡 문자열(String)은 참조 타입이지만, 기본 타입처럼 사용한다.
🔵 참조 타입의 특징
1. 스택 메모리에 값 대신 주소를 저장한다. 즉, 실제 데이터를 저장하는 것이 아니라, 데이터를 저장한 객체의 참조값(주소)를 저장한다.
2. 객체를 힙 메모리에 저장한다.
3. new를 이용하여 객체를 생성한 후 사용한다. 타입을 선언하고 값을 스택 메모리에 바로 저장하는 기본 타입과는 다르다.
Geo geol = new Geo();
geol.latitude = 37.5;
geol.longitude = 127.0;
📌 메모리 영역 (메소드, 힙, 스택)
메소드 영역
바이트코드 파일을 읽은 내용이 저장되는 영역
힙 영역
동적 메모리 할당에 사용되는 영역으로, 프로그램 실행 중에 런타임에 필요한 객체들을 저장하는 공간이다. 주로 객체를 생성하거나 배열과 같은 데이터 구조를 사용할 때 사용된다. 힙 메모리에 할당된 데이터는 GC(Garbage Collector)에 의해 관리되며, 더 이상 참조되지 않는 객체들은 자동으로 해제된다.
스택 영역
주로 메서드 호출과 관련된 데이터를 저장하는데 사용되며 선입선출(FILO, First In Last Out)의 구조로 작동한다. 함수가 끝나면 메모리에서 자동으로 제거된다.
1) 배열(Array) 타입
✅ 배열 생성
// 1. 배열을 선언하면서 동시에 초기화
int[] num1 = {1, 2, 3, 4, 5};
// num1 = {1, 2}; // ❌ 다시 생성 불가능 (컴파일 에러 발생)
// num1 = {4, 5, 6, 7, 8}; // ❌ 다시 초기화 불가능
num1 = new int[] {1, 2}; // ⭕ new 키워드를 사용하는 경우에는 가능 (새로운 배열 할당)
// 2. 배열을 선언한 후 나중에 초기화
int[] num2 = new int[5]; // 길이가 5인 배열 생성 (초기값: 0)
num2[0] = -1; // 배열 요소 값 변경 가능 (배열은 가변 객체)
// num2 배열을 새로운 크기의 배열로 변경
num2 = new int[4]; // ⭕ 다시 생성 가능 (기존 배열은 GC에 의해 제거됨)
// new 키워드를 사용하여 새로운 배열로 다시 초기화
num2 = new int[] {1, 2, 3, 4, 5}; // ⭕ 다시 초기화 가능
💡 new 연산자로 배열을 처음 생성하면 배열 항목은 기본값으로 초기화됩니다. (정수 배열은 0, 실수 배열은 0.0, 논리 배열은 false, 참조 배열은 null)
✅ 다차원 배열 생성
// 1. 2차원 배열 선언과 동시에 초기화
int[][] matrix1 = { // 3x3 배열
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 2. 2차원 배열을 선언한 후 초기화
int[][] matrix2 = new int[2][3]; // 2x3 배열 (초기값: 0)
matrix2[0][0] = 1;
// 3. 3차원 배열 선언과 동시에 초기화
int[][][] cube1 = { // 2x2x2 배열
{
{1, 2},
{3, 4}
},
{
{5, 6},
{7, 8}
}
};
// 4. 3차원 배열을 선언한 후 초기화
int[][][] cube2 = new int[2][2][2]; // 2x2x2 배열 (초기값: 0)
cube2[0][0][0] = 1;
✅ 배열 복사
import java.util.Arrays;
public class ArrayCopyExample {
public static void main(String[] args) {
int[] original = {1, 2, 3, 4, 5};
// 1. for문을 사용한 배열 복사
int[] copy1 = new int[original.length];
for (int i = 0; i < original.length; i++) {
copy1[i] = original[i];
}
// 2. System.arraycopy()를 사용한 배열 복사
int[] copy2 = new int[original.length];
System.arraycopy(original, 0, copy2, 0, original.length);
// 3. clone() 메서드를 사용한 배열 복사
int[] copy3 = original.clone();
// 4. Arrays.copyOf()를 사용한 배열 복사
int[] copy4 = Arrays.copyOf(original, original.length);
}
}
2) 열거(Enum) 타입
한정된 값을 갖는 데이터입니다. 요일(월, 화, 수, 목, 금, 토, 일)이나 계절(봄, 여름, 가을, 겨울)이 열거 타입 데이터에 해당됩니다.
enum Day {
MONDAY("월요일"),
TUESDAY("화요일"),
WEDNESDAY("수요일"),
THURSDAY("목요일"),
FRIDAY("금요일"),
SATURDAY("토요일"),
SUNDAY("일요일");
private String koreanDay;
// 생성자
Day(String koreanDay) {
this.koreanDay = koreanDay;
}
// 메서드
public String getKoreanDay() {
return koreanDay;
}
}
public class EnumExample {
public static void main(String[] args) {
Day today = Day.MONDAY;
System.out.println("오늘은 " + today.getKoreanDay() + "입니다.");
}
}
3) 클래스(Class)
클래스는 객체를 생성하기 위한 틀(설계도)로, 필드(변수)와 메서드(기능)로 구성됩니다. `new` 키워드를 사용하여 객체를 생성하며, 사용자가 원하는 데이터와 기능을 하나의 단위로 묶어서 관리할 수 있습니다.
✅ 클래스 예제
class Car {
String model;
int year;
void drive() {
System.out.println(model + "가 달립니다.");
}
}
a. 문자열(String) 타입
String은 기본 타입처럼 사용할 수 있는 특별한 클래스로, 문자열을 저장하고 조작하는 기능을 제공합니다. 특징적인 점은 한 번 생성된 문자열은 변경할 수 없는(Immutable) 객체라는 것입니다. 또한, new 키워드를 사용하지 않아도 문자열을 생성할 수 있습니다. 문자열을 다양한 방식으로 활용하는 방법을 예제와 함께 알아보겠습니다.
✅ 문자열의 생성
// 문자열 리터럴이 동일하므로 String 객체를 공유: 동일한 String 객체의 번지 저장
String name1 = "홍길동";
String name2 = "홍길동";
// name1과 name2는 같은 객체를 참조
// == 비교시 true를 반환
System.out.println(name1 == name2); // true
// new 연산자를 사용해 새로운 객체 생성: 서로 다른 String 객체의 번지 저장
String name3 = new String("홍길동");
String name4 = new String("홍길동");
// name3과 name4는 서로 다른 객체를 참조
// == 비교시 false를 반환
System.out.println(name3 == name4); // false
✅ 문자열의 불변성(Immutable)
String str = "Java";
str = str + " Programming"; // 기존 문자열이 변경되는 것이 아니라, 새로운 문자열이 생성됨
System.out.println(str); // Java Programming (원본 문자열은 변하지 않음)
✅ 다양한 활용
String str = "Hello Java"
// 문자열 추출
char c = str.charAt(3); // 'l'
// 문자열 길이
int length = str.length(); // 10
// 문자열 대체
String newStr = str.replace("Java", "자바"); // "Hello 자바"
// 문자열 잘라내기
String ssn = "010329-3234567";
String firstNum = ssn.substring(0,6); // 010329
String secondNum = ssn.substring(7); // 1234567
// 문자열 찾기
int index = str.indexOf("Java"); // 6
int index2 = str.indexOf("자바"); // 포함되어 있지 않으므로 -1
// 문자열 포함여부 확인
boolean result = str.contains("Hello"); // true
// 문자열 분리
String board = "사과,포도,바나나,딸기";
String[] arr = board.split(","); // {사과, 포도, 바나나, 딸기}
4) 인터페이스
클래스가 따라야 할 메서드의 규약(틀) 을 정의한 것으로, `interface` 키워드를 사용하여 선언합니다. 인터페이스에는 메서드의 선언만 존재하고, 실제 구현(몸체)은 없으므로 이를 구현하려면 `implements` 키워드를 사용하여 클래스에서 해당 메서드를 정의해야 합니다.
interface Animal {
void sound();
}
class Dog implements Animal {
public void sound() {
System.out.println("멍멍");
}
}
3. 타입 변환 (형 변환)
작은 타입은 큰 타입으로 자동 변환되지만, 큰 타입을 작은 타입으로 변환할 때는 (변환하려는 타입) 형식으로 타입 변환해서 사용합니다.
📌 허용 범위 순
byte < short, char < int < long < float < double
💡 큰 허용 범위 타입 = 작은 허용 범위 타입 (👉🏻자동 타입 변환)
// 📌 자동 타입 변환
// byte 타입이 int 타입으로 자동 변환되는 경우
byte byteValue = 10;
int intValue = byteValue;
// char 타입이 int 타입으로 자동 변환되는 경우 -> 유니코드 값이 int 타입에 대입됨
char charValue = 'A';
int charToInt = charValue; // 65 (유니코드 값)
// 💡 예외: byte 타입은 char 타입으로 자동 변환될 수 없음 (char는 음수 X)
// 📌 강제 타입 변환
// 실수를 정수로 변환
double d = 3.14192;
int i = (int) d; // (변환하려는 타입)
int random = (int) (Math.random() * 45); // Math.random()은 0.0 <= x < 1.0 사이의 임의의 실수 반환
// 숫자형 문자를 정수로 변환
int num = '8' - '0'; // 56 - 48 = 8, ASCII 참고
int a = Character.getNumericValue('9'); // 9
int b = Character.digit('9', 10); // 9
// ASCII를 숫자로 변환
int alpha = 'A'; // 65
char cAlpha = (char) 97; // 'a' -> (int) 'a' = 97
// 정수 연산은 결과도 정수
int x = 90;
int y = 95;
int z = 98;
int average = (x + y + z) / 3; // 실제 결과는 94.33이지만 정수 94를 반환
// 화씨를 섭씨로 변환
public static double toCelsius(double fahrenheit) {
return 5.0 / 9 * (fahrenheit - 32);
}
// 현재 시간 (밀리초 → 일 변환)
long days = System.currentTimeMillis() / 1000 / 60 / 60 / 24;
int day = (int) days;
// 💡 상수 선언 (static final 사용)
public class SwitchMain {
public static final int MATH = 83; // 수학 점수
public static final int KOR = 94; // 국어 점수
}
⭐ 문자열 → 기본 타입의 변환
변환 타입 | 예시 |
String → byte | byte value = Byte.parseByte("문자열"); |
String → short | short value = Short.parseShort("문자열"); |
String → int | int value = Integer.parseInt("문자열"); |
String → long | long value = Long.parseLong("문자열"); |
String → float | float value = Float .parseFloat ("문자열"); |
String → double | double value = Double.parseDouble("문자열"); |
String → boolean | boolean value = Boolean.parseBoolean("문자열"); |
*기본 타입 → 문자열의 변환: String.valueOf("기본타입값")
2️⃣ 제어문
프로그램은 기본적으로 위에서 아래로 순차적으로 실행되지만, 상황에 따라 흐름을 제어해야 합니다. 제어문을 사용하여 프로그램의 흐름을 변경할 수 있으며, 이를 활용해 다양한 알고리즘을 구현할 수 있습니다.
1. 조건문
1) if문
if (조건식) { 조건문1 }
if (조건식) { 조건문1 } else { 조건문2 }
if (조건식1) { 조건문1 } else if (조건식2) { 조건문2 } else { 조건문3 }
조건식에서 동일 여부나 대소 비교를 합니다.
조건식이 true이면 조건문1 구문이 실행되고 조건식이 false이면 (else가 있을 경우) 조건문2 구문이 실행됩니다. else if의 경우에는 여러 개 사용할 수 있습니다.
int v = 100;
if (v % 2 == 0) {
System.out.println("짝수");
} else {
System.out.println("홀수");
}
// 삼항 연산자로 표현 가능
String answer = (v % 2 == 0) ? "짝수" : "홀수";
System.out.println(answer); // 짝수
2) swich문
switch(입력변수) {
case 입력값1:
실행 코드
break;
case 입력값2:
실행 코드
break;
...
default:
실행 코드
break;
}
switch문은 정수형(`int`), 문자형(`char`), 문자열(`String`) 값을 비교하여 해당하는 case 부분을 실행합니다. 단, 대소 비교(>, < 등)는 불가능합니다.
public static int grade(char c) {
int score = 0;
switch (c) {
case 'A':
score = 100;
break;
case 'B':
score = 80;
break;
case 'C':
score = 60;
break;
case 'D':
score = 40;
break;
case 'F':
score = 0;
break;
default:
score = 0;
break;
}
return score;
}
2. 반복문
1) for문
for (초기값 ; 조건식 ; 증감식) { 조건문 }
조건이 true이면 계속 반복되고 false가 되면 종료됩니다.
// 1부터 10까지 합 구하기
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
System.out.println("총합: " + sum);
✅ 초기값 또는 증감식이 생략될 수도 있음
int n = 2345;
int tot = 0;
for (; n > 0;) { // while문과 비슷한 형태
tot += n % 10;
n /= 10;
}
System.out.println("각 자리의 합: " + tot);
✅ 향상된 for문
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.println(num);
}
2) while문, do-while문
while (조건식) { 조건문 }
do { 조건문 } while (조건식)
조건식이 true일때 조건문이 실행됩니다. 조건식이 처음부터 거짓이라면 한 번도 실행되지 않을 수도 있습니다. 따라서 while과 동일하지만 적어도 한 번 실행할 때는 do ~ while을 사용합니다.
✅ while문 예제
// 숫자의 각 자리의 합 구하기
int n = 2345;
int tot = 0;
while (n > 0) {
tot += n % 10;
n /= 10;
}
System.out.println("각 자리의 합: " + tot);
✅ do-while문 예제
int num = 0;
while (num > 0) {
System.out.println("실행되지 않음");
}
do {
System.out.println("최소 한 번 실행됨");
} while (num > 0);
반복 횟수가 명확할 때나 카운터 변수가 필요할 때는 for문이 유리하고,
반복문 횟수가 정해져 있지 않거나 조건에 따라 언제 종료될지 모를 때는 while문이 유리하다.
3. 분기문
1) break문
for문, while문, do-whild 문, switch문을 종료할 때 사용합니다. 중첩된 반복문의 경우 가장 가까운 반복문만 종료하므로 바깥쪽 반복문을 종료시키려면 Label을 사용합니다.
✅ 중첩된 반복문 예제
Label: for (...) {
for(...) {
break Label;
}
}
2) continue문
for문, while문, do-while문에서 사용됩니다. continue문이 실행되면 현재 반복의 나머지 부분은 건너뛰고 for문의 증감식 또는 while문, do-while문의 조건식으로 바로 이동합니다. 반복문을 종료하지 않고 계속 반복을 수행한다는 점에서 break문과 차이가 있습니다.
3) return문
메서드의 실행을 종료하고 값을 반환하는 데 사용됩니다. return문은 메서드가 `void`일 경우에는 값 없이 메서드를 종료할 때 사용되고, 값을 반환하는 메서드에서는 반환할 값을 함께 지정해야 합니다.
✅ 값 반환 예제
public int sum(int a, int b) {
return a + b; // 두 값을 더한 결과를 반환
}
✅ void 메서드에서의 종료 예제
public void printMessage() {
System.out.println("메시지 출력");
return; // 메서드 종료
}
'☕ Java' 카테고리의 다른 글
[Java Library] QueryDSL (0) | 2024.09.23 |
---|---|
[Java] 자바 메서드(Method) 총정리 (0) | 2024.09.22 |