변수
: 자료를 저장하기 위한 메모리 공간 (=그릇)타입
: 데이터의 형태Strongly Typed Language
== 변수 선언 시 타입을 명시해야 한다.var
키워드를 통해서 로컬 변수를 선언할 수 있다.var a = 1;
리터럴 방식 : “ “
사용 → String Pool
에 저장된다.
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); // true (같은 주소 참조)
System.out.println(str1.equals(str2)); // true (문자열 내용 같음)
new String() 방식 : Heap
에 새로운 객체가 생성된다.
→ Heap은 자바의 new
키워드로 생성되는 객체가 저장되는 공간이다.
String str3 = new String("hello");
String str4 = new String("hello");
System.out.println(str3 == str4); // false (서로 다른 객체)
System.out.println(str3.equals(str4)); // true (문자열 내용 같음)
public class FormatExample {
public static void main(String[] args) {
double num = 123.4567;
System.out.printf("[%10.2f]%n", num); // 너비 10, 소수점 2자리 (오른쪽 정렬)
System.out.printf("[%-10.2f]%n", num); // 너비 10, 소수점 2자리 (왼쪽 정렬)
System.out.printf("[%010.2f]%n", num); // 너비 10, 소수점 2자리, 0으로 채움
}
}
// 결과
[ 123.46] // 너비 10, 오른쪽 정렬, 소수점 2자리
[123.46 ] // 너비 10, 왼쪽 정렬, 소수점 2자리
[0000123.46] // 너비 10, 0 채움, 소수점 2자리
public class ExplicitCasting {
public static void main(String[] args) {
double doubleVal = 9.78;
int intVal = (int) doubleVal; // 실수(double) → 정수(int) 강제 변환
System.out.println("double: " + doubleVal); // double: 9.78
System.out.println("int: " + intVal); // int: 9 (소수점 이하 버림)
}
}
오버플로우
가 발생할 수 있다.int bigNum = 130;
byte smallNum = (byte) bigNum; // int → byte 변환 (오버플로우 발생 가능)
System.out.println(smallNum); // -126 (오버플로우 발생)
public class ImplicitCasting {
public static void main(String[] args) {
int intVal = 100;
double doubleVal = intVal; // 정수(int) → 실수(double) 자동 변환
System.out.println("int: " + intVal); // int: 100
System.out.println("double: " + doubleVal); // double: 100.0
}
}
객체형
은 기본형과 달리 추가적인 속성과 기능을 포함한다.
.java
확장자를 가진 파일로 작성된다.- Java Compiler에 의해 바이트코드(.class)로 변환된다. 이는 사람이 읽을 수 있는 고급 언어가 아닌, JVM이 이해할 수 있는 이진 코드이다.
- JVM이 파일을 로드, Class Loader가 필요한 클래스를 메모리에 로드한다.
- 바이트코드 검증기가 코드의 안정성을 확인한 후, JIT(Just-In-Time) 컴파일러가 바이트코드를 네이티브 코드로 변환하여 최종 실행한다.
배열
: 동일한 타입의 데이터 0개 이상을 하나의 연속된 메모리 공간에서 관리하는 것int[] points = new int[3]; // points는 메모리에 있는 배열을 가리키는 참조형 변수이다.
int[] points = {1, 2, 3};
int[] points = new int[]{1, 2, 3};
→ String 리터럴 방식과 다르게, 배열은 두 방식 모두 Heap에 저장된다. String Pool은 String만 저장하는 Heap 내의 특수한 공간이기 때문이다. (String은 불변 객체라 가능)
public class ForEachExample {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50};
// for-each 문을 사용한 배열 반복
for (int num : numbers) {
System.out.println(num);
}
}
}
// 2차원 배열 선언 (4행 3열)
int[][] arr1 = new int[4][3];
// 선언과 동시에 초기화
int[][] arr2 = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
{10, 11, 12}
};
// 가변 배열 (각 행의 길이가 다름)
int[][] arr3 = new int[4][];
arr3[0] = new int[2]; // 첫 번째 행은 2개의 열
arr3[1] = new int[3]; // 두 번째 행은 3개의 열
arr3[2] = new int[1]; // 세 번째 행은 1개의 열
arr3[3] = new int[4]; // 네 번째 행은 4개의 열
코드 | 설명 | 올바른가? |
---|---|---|
int intArray1[][] = new int[4][3]; | (정상) 4x3 크기의 2차원 배열 생성 | ✅ |
int[] intArray2[] = new int[4][3]; | (정상) 배열 선언 방식 변경 (int[][] 와 동일) | ✅ |
int [][] intArray3 = new int[4][]; | (정상) 가변 배열을 위한 선언 (열 개수 미지정) | ✅ |
int [] intArray4 = new int[4]{1,2,3}; | 🚨 (오류) 배열 크기가 4인데, 3개의 값만 넣었음 | ❌ |
int [][] intArray5 = new int[][] {{1,2,3},{1,2,3},{1,2,3},{1,2,3}}; | (정상) 4x3 크기의 배열 초기화 | ✅ |
int [][] intArray6 = {{1,2,3},{1,2,3},{1,2,3},{1,2,3}}; | (정상) 배열 리터럴 방식 사용 | ✅ |
var
에 대해서 학습할 수 있었다.
리터럴 방식, String Pool
, Heap
에 대해 학습할 수 있었다.
명시적 형변환을 할 때 오버플로우
가 발생할 수 있음을 알게 되었다.
가변 배열에 대해 알 수 있었다.