main 메서드 외부에 필드를 선언하면 main 내부에서 호출되지 않는 이유
- 객체를 생성하지 않으면 인스턴스 필드는 메모리에 올라가지 않기 때문.
- static이 없는 필드는 인스턴스 멤버이므로 객체를 생성해야 접근할 수 있음.
JDK 구조
- JDK 내부에는 JRE가 포함됨.
- JRE 구성 요소: ClassLoader(CL), Bytecode Verifier(BV), Memory Management(MG), rt.jar (런타임 라이브러리), JVM.
new 키워드
- 객체를 힙(Heap) 메모리에 올릴 때 사용.
생성자의 역할
- "생성자는 객체의 초기화 역할을 한다"는 표현은 부정확함.
- 정확히는 "생성자 호출 시 객체가 메모리에 올라가고, 이를 통해 non-static 멤버를 초기화할 수 있음."
- 생성자는 호출될 때 필요한 초기화 코드를 실행하지만, 객체의 메모리 할당 자체는 new 키워드가 수행함.
Strings
String s1 = new String("java");
String s2 = new String("java");
System.out.println(s1==s2); // false 출력. 서로 다른 객체를 가르킴. 시간복잡도 O(n)
String s3 = "java";
String s4 = "java";
System.out.println(s3==s4); // true 출력. s3, s4는 같은 객체 주소를 가르킴. 시간복잡도 O(1)
하지만 만약 s3를 변경해도 s4는 변경되지 않음. String은 불변 객체이므로 변경이 불가능함. 새로운 s3 객체를 생성하게 됨
String s1 = new String("java");
String s2 = new String("java");
System.out.println(s1 == s2); // false
- new String("java")는 Heap 메모리에 새로운 객체를 생성함.
- s1과 s2는 서로 다른 객체의 주소를 가리킴, 따라서 == 비교 결과는 false.
- 시간 복잡도 O(n): new String("java")는 내부적으로 문자열을 복사하는 과정이 포함되므로, 길이에 따라 O(n) 비용이 발생할 수 있음.
String s3 = "java";
String s4 = "java";
System.out.println(s3 == s4); // true
- 리터럴("java")을 사용하면 String Constant Pool(문자열 상수 풀) 에 저장됨.
- s3와 s4는 동일한 객체의 주소를 가리킴, 따라서 == 비교 결과는 true.
- 시간 복잡도 O(1): 같은 문자열 리터럴이 이미 존재하면 새 객체를 생성하지 않고 기존 객체의 참조를 반환하므로 O(1).
concat : 이어쓰기
String s1 = "java";
인스턴스에 주소와 값 들어감. 스택영역에는 뭐가 들어감? SLP영역에는 뭐가들어감??
String에 int를 추가하게 되는 경우 동작원리
int를 추가하면 새로운 인스턴스 객체가 생성됨
String s = "java";
for (int i = 0; i < 5; i++) {
s += i;
System.out.println(s);
}
i가 추가될 때마다 새로운 객체 인스턴스가 생성됨. 기존 인스턴스 객체는 GC에 의해 삭제될 수 있음
이렇게 추가, 삭제가 반복되는 불필요한 과정을 줄이기 위해 StringBuffer 사용
concat
- 문자열 이어쓰기
- String은 불변(immutable) 객체이므로, concat을 사용해도 기존 문자열이 변경되지 않고 새로운 String 객체가 생성됨.
String s1 = "java";
s1 = s1.concat("Script"); // 새로운 객체 생성
System.out.println(s1); // "javaScript"
String s1 = "java"; 저장구조
1. 스택(Stack) 영역
s1 변수(참조 변수)가 저장됨.
s1에는 String 객체의 참조값(주소) 이 저장됨.
2. String Literal Pool(SLP, 문자열 상수 풀) 영역
"java" 문자열이 SLP(문자열 상수 풀) 에 저장됨.
같은 리터럴이 존재하면 새로운 객체를 만들지 않고 기존 객체의 참조를 반환함.
3. 힙(Heap) 영역 (new String() 사용 시)
new String("java")를 사용하면 Heap 영역에 새로운 String 객체가 생성됨.
그러나 SLP에는 "java" 리터럴이 별도로 존재할 수 있음.
따라서 "java" 리터럴과 new String("java")는 서로 다른 객체.
String에 int를 추가하는 경우 동작 원리
String s1 = "java";
s1 = s1 + 100;
System.out.println(s1); // "java100"
100은 int 타입이므로 자동으로 String으로 변환됨
"java" + "100" → 새로운 String 객체가 생성됨.
s1이 새로운 "java100" 객체를 가리키고, 기존 "java" 객체는 변경되지 않음.
문자열 반복 추가 시 문제점
String s = "java";
for (int i = 0; i < 5; i++) {
s += i;
System.out.println(s);
}
+= 연산을 사용할 때마다 새로운 String 객체가 생성됨.
기존 String 객체는 더 이상 참조되지 않으므로 GC(가비지 컬렉션)에 의해 삭제될 수 있음.
반복문이 커질수록 불필요한 객체 생성과 삭제가 성능 저하를 유발함.
StringBuffer, StringBuilder
- String과 달리 불변 객체가 아님(가변, mutable) >> 기존 객체를 직접 수정함.
- 문자열 연산이 많을 때 성능 최적화 가능.
- + 연산자가 아닌 메서드(append(), insert(), delete())를 사용해야 함. + 연산자를 쓰면 String으로 변환되므로 StringBuffer를 쓰는 의미가 없음.
Methods
메서드는 반드시 리턴이 존재
- 메서드는 항상 리턴값을 가지며, 리턴값이 없으면 void를 사용해야 함.
- 리턴값이 있는 경우, 반환 타입을 메서드 앞에 선언해야 함.
메서드 안에서 또 다른 메서드 정의 불가능
-자바에서는 메서드 내부에 새로운 메서드를 선언할 수 없음.
메서드 호출 위치 제한
- 메서드는 반드시 메서드 내부에서 호출 가능.
- 데이터 영역(클래스 변수 선언부)에서는 메서드 호출 불가능.
- main 메서드 밖에서 직접 호출 불가능.
메서드 호출 방식 (static vs 인스턴스 메서드)
- 객체 인스턴스를 생성하여 호출 가능
- static 메서드는 객체 생성 없이 호출 가능
- 객체 지향적으로 static 없이 사용하는 것이 좋음 (static은 계속 메모리에 남아있음)
static 사용 시 주의점
- static 메서드는 객체 없이도 호출 가능하지만, 계속 메모리에 남아 있음.
- 객체 지향적으로는 static을 최소화하고, 인스턴스 메서드를 사용하는 것이 바람직함.
JVM의 메서드 실행 과정
JVM이 클래스를 로드 (ClassLoader) >> main 제외 static 멤버 초기화 >> 상속 관계 확인 (상속받은 부모 클래스의 필드, 메서드 로드) >> main 메서드 실행
메서드를 main 밖으로 분리하는 것이 권장됨
- 메서드를 main 내부가 아닌 클래스 내부에서 정의 후 호출하는 것이 좋음.
- 더 나아가, 메서드를 별도의 클래스로 분리하는 것이 가장 좋은 구조.
method overloading
- 같은 이름을 가진 메서드를 여러 개 정의할 수 있는 기능
- 같은 기능을 수행하지만, 인자의 타입이나 개수에 따라 다르게 동작하도록 구현
- 매개변수의 타입, 개수, 순서 중 하나 이상이 달라야 함.
- 매개변수 이름만 다르면 오버로딩이 성립하지 않음
- 매개변수 타입이 일치하지 않는 경우, 명시적 형변환(casting)을 통해 특정 메서드와 연결 가능
method scope : 메서드 호출 시에 해당 메서드로 이동, 끝나면 호출 시 위치로 복귀
blcok scope : {}(중괄호)로 구분되는 범위 안에서 선언된 변수는 해당 블록에서만 유효, 가능하면 블록 내에서 복잡한 로직을 넣기보다는 메서드로 분리하는 것이 권장됨
OOP
재사용 가능한 코드를 만들기 위한 프로그래밍 기법
객체(객체 모델링)를 기반으로 프로그램을 설계하고 구현하는 방식
실제 세상의 개념(고객, 상품, 구매 등)을 코드로 표현하여 직관적이고 유지보수하기 쉬운 구조를 만듦
클래스 : 객체를 생성하기 위한 설계도, 프로그램 단위 (코드), 객체의 속성(변수)과 동작(메서드)을 정의
객체 : 클래스를 통해 만들어진 실체(메모리 상에 할당된 데이터) ,내 머릿속의 개념(고객, 상품, 구매 등)을 컴퓨터에 올려 메모리 속에서 다룰 수 있게 만든 것
OOP의 3대 concept
1. encapsulation (은닉화)
데이터를 유효하게 사용하는 방법
접근 제어자 를 사용하여 클래스 내부의 속성이나 메서드에 접근을 제한
목적: 외부에서 클래스의 내부 구현을 숨기고, 안전하게 데이터를 처리할 수 있도록 함
private | (default) | protected | public |
자기 클래스 내에서만 접근 가능 | 같은 패키지 내에서만 접근 가능 | 다른 패키지라도 상속 관계에 있으면 접근 가능 | 어디서나 접근가능 |
- class 앞 : (default), public
- data 앞 : 4가지중 1가능
- method 앞 : 4가지 중 1가능
유효성 검사를 포함한 setter/getter 메서드는 객체의 속성 값이 유효한지 확인한 후, 해당 값을 설정하거나 반환하는 방식으로 구현
2. inheritance (상속)
부모 클래스의 속성과 메서드를 자식 클래스가 물려받는 것
extends 키워드를 사용
- toString(): 객체의 메모리 주소를 반환
- hashCode(): 객체를 고유하게 식별하는 유일한 값 반환
- equals(): 두 객체가 동일한지 비교 (주소값 비교)
3. polymorphism (다형성)
하나의 객체가 여러 가지 형태를 가질 수 있는 능력
메서드 오버로딩: 같은 이름의 메서드를 매개변수의 개수나 타입을 다르게 하여 여러 형태로 정의
메서드 오버라이딩: 부모 클래스의 메서드를 자식 클래스에서 재정의하여 다르게 동작하게 만들기
1. 알고리즘 공부 사이트 가입.
2. 배열 - 공부 w3school 1차원, 2차원 문법
3. 배열 문제 찾아서 같이 풀어보기
4. 스터디 노트에 조별 스터디 한거 추가. 그 외 추가로 공부한 거 넣기
배열(Arrays)
같은 타입의 데이터를 연속적인 메모리 공간에 저장. 배열의 크기는 고정, 한번 선언된 배열의 크기는 변경할 수 없음. 배열은 인덱스를 사용하여 각 요소에 접근. 인덱스는 0부터 시작
// 배열 선언
int[] arr = new int[5]; // 크기 5인 배열 생성
// 배열 초기화
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
선언 및 초기화
int[] arr = {10, 20, 30, 40, 50};
한 번에 선언 및 초기화
- 2차원 배열
int[][] arr2D = new int[1][3]; // 1행 3열의 배열 생성
// 배열 초기화
arr2D[0][0] = 1;
arr2D[0][1] = 2;
arr2D[0][2] = 3;
System.out.println("배열의 크기: " + arr.length); // 1차원 배열 크기
System.out.println("2차원 배열의 행 크기: " + arr2D.length); // 행의 크기
System.out.println("2차원 배열의 열 크기: " + arr2D[0].length); // 열의 크기
배열 크기 length 속성으로 확인 가능
배열 기본값
- int 배열은 0으로 초기화
- boolean 배열은 false로 초기화
- 객체 배열은 null로 초기화
'[LG 유플러스] 유레카 > Today I Learned' 카테고리의 다른 글
[TIL][02.11] Modifier, Interface, String, Wrapper, Inner, lambda, Generics, Comparable, Comparator (0) | 2025.02.12 |
---|---|
[TIL][02.10] 배열, 상속, 다형성, abstract (0) | 2025.02.10 |
[TIL][02.06] JAVA, JVM, TYPE, Garbage Collection (0) | 2025.02.06 |
[TIL][02.05] implements, inheritance, override, abstract, generic, utility (0) | 2025.02.05 |
[TIL][02.04] Array Iteration, Map, TS (0) | 2025.02.04 |