자바의 메모리 구조
- 메서드 영역 : 클래스에 대한 정보 (클래스 이름, 변수, 메서드, static 변수) 저장. 모든 스레드가 공유
- 힙 영역 : new 키워드로 생성한 객체들이 저장되는 공간. 모든 스레드가 공유하며, 가비지 컬렉터가 이 영역을 관리함
- 스택 영역 : 메서드 호출 시 생성되는 지역 변수들이 저장됨. 각 스레드마다 따로 존재. 메서드 호출이 끝나면 해당 스택은 자동으로 제거
- 프로그램 카운터 레지스터 : 현재 실행 중인 JVM 명령어 주소를 저장합니다. 스레드마다 하나씩 존재
- 인텔리제이에서 자주 사용하는 단축키 Ctrl + J 단축구문 전체 팝업
sout System.out.println(); 자동완성 serr System.err.println(); 자동완성 main / psvm public static void main(String[] args) { } 자동완성 Alt + Insert 생성자, getter/setter 메서드 자동 생성 (cmd + N on Mac) Shift + Enter 커서 위치에 상관없이 다음 줄 생성 Ctrl + Shift + ↑/↓ 현재 줄 위/아래로 이동 (라인 위치 바꾸기) Ctrl + I 상속받은 메서드 자동완성 Ctrl + Shift + U 대/소문자 전환 Alt + Enter 오류/경고 위에서 대체 옵션 제안 F2 다음 오류/경고/제안으로 이동 Ctrl + B 변수/클래스/메서드 선언부로 이동 Ctrl + / 현재 줄 주석 처리 (//) Ctrl + Shift + / 블록 주석 처리 (/* */) Ctrl + Enter 조건문 괄호 입력 후 {} 자동 생성 Ctrl + Shift + Enter 조건문 전체 문장 자동완성 (if, for 등) Ctrl + Alt + L 코드 자동 줄맞춤 (포맷팅) Shift + Shift 전체 검색 (클래스, 파일, 심볼 등) Ctrl + Y 현재 줄 삭제 Ctrl + D 현재 줄 복사하여 아래에 붙여넣기 Ctrl + Alt + O import 문 최적화 Ctrl + Alt + T 선택한 코드 블록으로 감싸기 (if, try, for 등) Ctrl + R 찾은 문자열을 다른 문자열로 바꾸기 Shift + F6 변수/파일 이름 바꾸기 (리팩토링) Ctrl + Alt + S 설정(Settings) 창 열기 Ctrl + Alt + Shift + S Project Structure 창 열기 Ctrl + . 접기(Folding) 기능 – 코드 일부를 ...으로 축약
변수
자바에서 변수는 값을 저장하기 위한 이름이 붙은 메모리 공간
프로그램이 데이터를 일시적으로 기억하고 활용할 수 있게 해줌
변수는 사용하기 전에 반드시 선언해야하고, 선언 시에는 자료형 (예 : int, double, String)과 함께 변수 이름을 명시한다.
자바는 정적 타입 언어. 변수의 자료형이 고정됨. 다른 자료형의 값을 저장하려 하면 컴파일 에러 발생
선언된 위치와 사용 방법에 따라 **지역 변수, 멤버 변수(필드), 클래스 변수(static)**로 나눠짐
자바 변수 이름 규칙 (필수)
- 영문자, 숫자, 밑줄, 달러 기호 사용 가능
- 숫자로 시작할 수 없음
- 자바 예약어는 변수명으로 사용할 수 없음
선언과 저장
자료형 변수 이름; → 변수 선언
변수 이름 = 값 → 값 저장(대입)
int age; -> 변수 선언
double height; -> 실수형 변수 height 선언
String name; -> 문자열을 저장할 변수 name 선언
age = 20;
height : 160.5
name = "김사과"
System.out.println("이름: " + name);
System.out.println("나이:" + age);
System.out.println("키: "+ height);
------------------------------------------
이름: 김사과
나이:20
키: 160.5
데이터 타입
변수에 어떤 종류의 데이터를 저장할 수 있는지 정해주는 설명서 → 변수에 숫자를 저장할지, 글자를 저장할지, 참/거짓을 저장할지 자바에 미리 알려주는 것
예전에는 메모리를 아껴쓰려고 데이터 타입을 잘 지켰다. 요즘은 메모리<속도 이기 때문에
1. 기본형 데이터 타입 (Primitive Types) - 총 8가지 타입
스택에 직접 저장하는 것
- byte (1바이트) : -128 ~ 127 정수
- byte a = 100;
- short(2바이트) : 작은 정수 30000대
- short b = 30000;
- ⭐int(4바이트) : 일반적인 정수 타입
- int c = 100000;
- long(8바이트) : 큰 정수, 끝에 L 붙이기
- long d = 1000000000000L;
- float(4바이트) : 소수점 숫자, 끝에 f
- float e = 3.14f;
- ⭐double(8바이트) : 더 정밀한 소수
- double f = 3.141592;
- char(2바이트) : 한 글자 문자형(매핑되어있는 숫자 가능), 작은따옴표 ‘’ 사용
- char g = ‘A’;
- 아스키 코드 : 문자를 숫자로 표현 (매핑되어있음)
- boolean(1바이트, 논리값) : True, false
참조형 데이터 타입 (Reference Types)
기본형이 아닌 모든 데이터
실제 데이터가 있는 메모리 주소를 변수에 저장함
- String : 문자열 저장 (한 글자 이상)
- String name = “홍길동”;
- 배열 : 같은 타입의 데이터를 여러 개 저장
- int numbers = {1, 2, 3};
예제 : Ex02_DataType.java
package lesson01;
public class Ex02_DataType {
public static void main(String[] args) {
// main : jvm이 가장 먼저 자동으로 실행시켜주는 메서드, 함수 역할을 하는 것
int age = 20; // 정수형
double height = 160.5; // 실수형
char grade = 'A'; // 문자형 (한 글자)
boolean isStudent = true; // 관례상 is로 시작하면 논리형
String name = "김사과"; // 문자열 (참조형)
System.out.println("이름:" + name);
System.out.println("나이:" + age);
System.out.println("키:" + height);
System.out.println("학점:" + grade);
System.out.println("학생여부:" + isStudent);
}
}
----------------------------------------------------------------------
이름:김사과
나이:20
키:160.5
학점:A
학생여부:true
형 변환
변수나 값의 자료형을 다른 자료형으로 바꾸는 과정
숫자 타입 간 (int → double)에는 자동 변환이 가능.
크기가 큰 타입에서 작은 타입으로 바꿀 때에는 **명시적 형 변환(casting)**이 필요함 (double → int)
계산, 저장, 비교 등의 작업에서 타입이 서로 다를 때 사용됨.
잘못 사용하면 데이터 손실 발생할 수 있으니 주의
자동(묵시적) 형 변환
int num = 100;
double result = num; // int → double 자동 변환
System.out.println(result); // 출력: 100.0
강제(명시적 형 변환)
괄호 안에 바꿀 자료형 넣어주기!!
double pi = 3.14159;
int intPi = (int) pi; // double → int 명시적 형 변환
System.out.println(intPi); // 출력: 3
< 주의해야하는 상황 : 엉뚱한 숫자가 나오기도 함>
int i = 1000;
byte b = (byte) i ;
System.out.println(b); ⇒ ?
예제 : Ex_03TypeCasting.java
package lesson01;
public class Ex_03TypeCasting {
public static void main(String[] args) {
int score = 90;
double average = score;
System.out.println("자동 형 변환 결과 :" + average);
double pi = 3.14159;
int truncatedPi = (int) pi;
System.out.println("강제 형 변환 결과 : " + truncatedPi);
char grade = 'A';
int gradeCode = grade;
System.out.println("문자 A의 유니코드 값 : " + gradeCode);
// 문자도 아스키 코드이기 때문에 유니코드 값으로 찍힘
int code = 66; // 'B'
char letter = (char) code; // 66이 2바이트에는 넣을 수 있긴 함
System.out.println("유니코드 66에 해당하는 문자는 : " + letter);
}
}
float(실수 4바이트) vs long(정수 8바이트) : 누가 더 큰 타입일까? ⇒ long < float
크기를 비교할 땐 표현할 수 있는 값의 종류와 범위를 기준으로 봐야함
예제 : Ex04_FloatLong.java
package lesson01;
public class Ex04_FloatLong {
public static void main(String[] args) {
long bigNumber = 100000000000L; // long 타입
float converted = bigNumber; // long → float (자동 형 변환, 정밀도 손실)
System.out.println("long → float 변환: " + converted);
float pi = 3.14159f;
long piToLong = (long) pi;
System.out.println("float -> long 변환:" + piToLong);
}
}
연산자
계산 / 비교 등을 수행할 수 있도록 도와주는 기호 또는 예약어
산술 연산자
+ 덧셈 3 + 2 5
- | 뺄셈 | 5 - 2 | 3 |
* | 곱셈 | 4 * 2 | 8 |
/ | 나눗셈 | 5 / 2 | 2 (정수 나눗셈) |
% | 나머지 (mod) | 5 % 2 | 1 |
주의 : 정수끼리 나누면 소수점은 버려짐. 5 / 2 = 2, 소수를 얻으려면 5.0 / 2처럼 하나 이상이 실수여야 함
복합 대입 연산자
+= 더해서 대입 a += 3;
-= | 빼서 대입 | a -= 2; |
*= | 곱해서 대입 | a *= 5; |
/= | 나눠서 대입 | a /= 2; |
%= | 나머지 대입 | a %= 3; |
증감 연산자
++ 1 증가 a++ 사용 후 증가 (후위)
-- | 1 감소 | --a | 사용 전 감소 (전위) |
Scanner API
데이터 입력받는 걸 먼저 해볼게요~!
scanner
사용자로부터 키보드 입력을 받을 수 있게 해주는 표준 입력 처리 도구
java.util 패키지에 포함되어 있어서 임포트 해주면 된다.
숫자, 문자열 등 다양한 형식의 데이터를 쉽게 입력받을 수 있도록 도와줌 → 콘솔에서 입력을 받을 때 사용됨
scanner 사용 방법
- 먼저 import java.util.Scanner; 선언
- Scanner sc = new Scanner(System.in) 으로 객체 생성
- sc.nextInt(), sc.nextLine(), sc.nextDouble() 등 다양한 메서드를 사용해서 입력 ㅇ받음
- 사용이 끝나면 sc.close();를 호출해서 자원 정리함
메서드 정리
next() 단어 하나 (공백 전까지) 읽음
nextLine() | 한 줄 전체 입력 (공백 포함) |
nextInt() | 정수 입력 |
nextDouble() | 실수 입력 |
nextBoolean() | true/false 입력 |
예제 : Ex05_Scanner.java
package lesson01;
import java.util.Scanner;
public class Ex05_Scanner {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 글을 쓸 수 있는 input 객체
System.out.print("이름을 입력하세요 :");
String name = sc.nextLine(); // 한 줄을 입력받을거예용!
System.out.print("나이를 입력하세요 :");
int age = sc.nextInt();
System.out.print("안녕하세요, " + name+ "님! 당신의 나이는" + age +"세입니다");
sc.close();
}
}
-----------------------------------
이름을 입력하세요 : 김사과
나이를 입력하세요 :34
안녕하세요, 김사과 님! 당신의 나이는34세입니다
** 주의 사항 **
nextInt() 후에 nextLine()을 바로 쓰면 입력이 꼬일 수 있습니다. 이때는 sc.nextLine()을 한 번 더 호출해서 버퍼를 비워줘야 함
순서 : Line → Int
int age = sc.nextInt();
sc.nextLine(); // 개행 문자 제거
String name = sc.nextLine();
System.in
표준 입력 장치를 의미. 키보드 입력을 받을 때 사용되는 입력 스트림
보통 Scanner, BufferedReader와 함께 사용되어 입력값을 읽음.
바이트 단위로 데이터를 읽음. 텍스트 입력을 더 쉽게 다루기 위해 보통 래퍼 클래스들과 함께 사용됨.
예제 : Ex06_SystemIn.java
package lesson01;
import java.io.IOException;
public class Ex06_SystemIn {
public static void main(String[] args) throws IOException {
System.out.print("문자 하나를 입력하세요 :");
int input = System.in.read(); // 한 글자(바이트)를 읽음
System.out.println("입력한 문자 :" + (char)input);
}
}
------------------------
문자 하나를 입력하세요 :R -> 숫자로 변환해서 저장했다가 char로 변환해서 아래에 찍어준 것
입력한 문자 :R
- 메소드에서 에러 처리 (try catch문 안써도 됨) : throws IOException
배열
같은 자료형의 값들을 여러 개 저장할 수 있는 연속된 공간
한 번 생성되면 크기가 고정(자바스크립트와 다른 점), 각 요소는 인덱스를 통해 접근할 수 있음.
배열을 사용하면 반복문과 함께 데이터를 효율적으로 처리할 수 있음
int[ ] String[ ] 처럼 자료형 뒤에 대괄호를 붙여서 선언함.
배열의 특징
- 같은 자료형만 저장 가능 (int[ ], String[ ] , double[ ] 등)
- 크기(길이)를 미리 정해야 함 → 한 번 정해지면 변경 불가
- 인덱스는 0부터 시작
배열 선언과 생성
자료형 [ ] 배열 이름 = new 자료형[크기];
int[] scores = new int[5]; // 정수형 5개를 저장할 수 있는 배열 생성(공간만 생성)
또는
int[] scores = {90, 80, 100, 70, 40}; // 배열 생성과 동시에 값을 저장
⇒ scores 자체는 배열을 직접 저장하는 게 아니라, 배열이 저장된 메모리의 위치(주소)르 참조하는 것
int[] a = {1, 2, 3};
int[] b = a; // 배열 a의 참조값을 b에 복사
b[0] = 99; // b 배열의 첫 번째 값을 변경
System.out.println(a[0]); // 출력: 99
⇒ a 배열도 같이 바뀜
예제 : Ex07_ArrayInput.java
package lesson01;
import java.util.Scanner;
public class Ex07_ArrayInput {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] scores = new int[3];
System.out.print("첫 번째 점수를 입력하세요 :");
scores[0] = sc.nextInt();
System.out.print("두 번째 점수를 입력하세요 :");
scores[1] = sc.nextInt();
System.out.print("세 번째 점수를 입력하세요 :");
scores[2] = sc.nextInt();
System.out.println("첫 번째 점수 : "+scores[0]);
System.out.println("두 번째 점수 : "+scores[1]);
System.out.println("세 번째 점수 : "+scores[2]);
sc.close();
}
}
----------------------------------------------------------
첫 번째 점수를 입력하세요 :90
두 번째 점수를 입력하세요 :50
세 번째 점수를 입력하세요 :70
첫 번째 점수 : 90
두 번째 점수 : 50
세 번째 점수 : 70
2차원 배열 (배열 안에 배열이 있는 구조)
1차원 배열을 요소로 가지는 배열. 즉 행(row)마다 각각의 1차원 배열이 따로 존재하는 것
- 1차원 배열 : int [ ]
- 2차원 배열 : int [ ] [ ] → 배열의 배열
- int [ ] [ ] matrix = new int [2] [3]; → 2행 3열 배열
int[][] arr = {
{1, 2, 3},
{4, 5, 6}
};
⇒ 2개의 행을 참조한다.
예제 : Ex08_JaggedArray.java
package lesson01;
public class Ex08_JaggedArray {
public static void main(String[] args) {
int[][] jagged = new int[3][];
// 가변 배열
jagged[0] = new int[] {1,2};
jagged[1] = new int[] {3,4,5};
jagged[2] = new int[] {6};
System.out.println("jagged[0][0] = " + jagged[0][0]);
System.out.println("jagged[0][1] = " + jagged[0][1]);
System.out.println("jagged[1][0] = " + jagged[1][0]);
System.out.println("jagged[1][1] = " + jagged[1][1]);
System.out.println("jagged[1][2] = " + jagged[1][2]);
System.out.println("jagged[2][0] = " + jagged[2][0]);
}
}
-------------------------------------------
jagged[0][0] = 1
jagged[0][1] = 2
jagged[1][0] = 3
jagged[1][1] = 4
jagged[1][2] = 5
jagged[2][0] = 6
얕은 복사와 깊은 복사
- 얕은 복사 : 객체나 배열의 참조값(주소)만 복사해서 원본과 복사본이 같은 데이터를 공유(한 쪽을 변경하면 다른 쪽에도 영향을 줌)
- 깊은 복사 : 새로운 메모리 공간을 만들고 원본의 값을 하나하나 복사해서 원본과 복사본이 독립적으로 동작하게 만드는 방식 (서로 영향을 주지 않음)
얕은 복사 (Shallow Copy)
int[] a = {1, 2, 3};
int[] b = a; // 얕은 복사
b[0] = 99;
System.out.println("a[0] = " + a[0]); // 99
System.out.println("b[0] = " + b[0]); // 99
깊은 복사 (Deep Copy)
새로운 공간을 만들고 값만 복사해옴
package lesson01;
public class Ex09_DeepCopy {
public static void main(String[] args) {
int[] a = {1,2,3};
int[] b = new int[3];
b[0] = a[0];
b[1] = a[1];
b[2] = a[2];
System.out.println("a[0] =" + a[0]);
System.out.println("b[0] =" + b[0]);
System.out.println("-------b[0] 값 바꿈----------");
// b 배열 값 변경
b[0] = 99;
// 결과 출력
System.out.println("a[0] =" + a[0]);
System.out.println("b[0] =" + b[0]);
}
}
----------------------------
a[0] =1
b[0] =1
-------b[0] 값 바꿈----------
a[0] =1
b[0] =99
'Programming > Java' 카테고리의 다른 글
메서드, return, 객체지향 프로그래밍, 객체, 생성자, 오버로딩 Null, 가비지컬렉터, 패키지, 상속, 메서드 오버라이딩, final (1) | 2025.06.02 |
---|---|
조건문 (if, else-if, switch, yield), 반복문 (while, do-while, for), Random 클래스, Break문, Continue, 향상된 for 문, 중첩 반복문 (4) | 2025.06.02 |
인터페이스, 예외처리 (0) | 2025.06.02 |
recode (0) | 2025.05.28 |
Set 계열, Map 계열, DTO, VO (0) | 2025.05.28 |