[공부 내용 정리]
자동 리소스 닫기(try-with-resource)
예외 발생 여부와 상관없이 리소스 객체의 close() 메소드를 호출해서 안전하게 리소스를 닫아줌.
- Autocloseable 인터페이스의 close() 메소드를 직접 구현하는 FileInputStream 클래스
public class FileInputStream implements AutoCloseable {
private String file;
public FileInputStream(String file) {
this.file = file;
}
public void read() {
System.out.println(file + " 을 읽습니다");
}
@Override
public void close() throws Exception {
System.out.println(file + "을 닫습니다");
}
}
public class TryWithResourceExample {
public static void main(String[] args) {
try (FileInputStream fileInputStream = new FileInputStream("file.txt")){
fileInputStream.read();
throw new Exception(); // 강제적으로 예외 발생시킴
} catch (Exception e) {
System.out.println("예외 처리 코드가 실행되었습니다.");
}
}
}
List 사용법
package chapter09;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
// List<Account> list = new ArrayList<>;
List<String> list = new ArrayList<>();
list.add("element1");
list.add("element2");
list.add("element3");
System.out.println(list);
}
}
→ add로 요소 추가 가능!!!
배열 코드 사용
- 배열은 크기가 정해져 있으며, 크기를 초과하여 데이터를 추가하려면 새로운 배열을 생성하여 데이터를 복사해야함.
- 배열의 요소를 추가하려면, 해당 인덱스에 값을 대입해야함.
- 배열의 요소를 제거하려면, 해당 인덱스의 값을 삭제하고, 빈 자리를 채우기 위해 나머지 요소를 한 칸씩 앞으로 이동시켜야함.
- // 배열 생성 int[] arr = new int[5]; // 값 추가 arr[0] = 1; arr[1] = 2; // 값 제거 arr[1] = 0; for (int i = 1; i < arr.length; i++) { arr[i-1] = arr[i]; } arr[arr.length-1] = 0;
리스트 코드 사용
- 리스트는 크기가 가변적이며, 요소를 추가하거나 제거할 때마다 자동으로 크기가 조절됨.
- 리스트의 요소를 추가하려면, add() 메서드 사용.
- 리스트의 요소를 제거하려면, remove() 메서드 사용.
// 리스트 생성
List<Integer> list = new ArrayList<>();
// 값 추가
list.add(1);
list.add(2);
// 값 제거
list.remove(1);
배열과 리스트의 차이점

- ex) 문제에서 n번이라는 크기가 정해졌을 때는 배열을 쓰고, 아무런 크기가 주어지지 않았을 땐 ArrayList를 사용함.
- 따라서, 배열은 크기가 고정적이지만 인덱스를 통해 빠르게 요소에 접근할 수 있는 반면, 리스트는 크기가 가변적이지만 요소를 추가하거나 제거할 때 편리하게 사용할 수 있음.
제네릭
제네릭(generic)이란 데이터의 타입을 일반화(generalize)한다는 것.
→ 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 것.
- 컴파일시 미리 타입이 정해지기 때문에, 타입 검사나 변환 같은 번거로운 작업을 생략할 수 있음.
- 클래스나 메소드 내부에서 사용하는 타입 안정성을 높일 수 있음.
제네릭을 사용하는 이유
- 컴파일시 강한 타입 체크를 할 수 있음.
- 컴파일시 미리 타입이 정해지기 때문에, 타입 검사나 변환 같은 번거로운 작업 생략 가능.
- 타입 안정성을 높일 수 있음.
- 타입 변환(casting)을 제거함.
- 불필요한 타입 변환을 할 필요가 없어서 성능이 향상됨.
ex)
ArrayList list2 = new ArrayList();
list2.add("str");
list2.add(1234);
list2.add(4.5);
String str3 = (String) list2.get(1);
String str4 = (String) list2.get(2);
→ 제네릭 사용 전 : 요소를 찾아올 때 String으로 타입 변환을 해야함
(list.get(0) 타입이 Object이기 때문)
ArrayList<String> list2 = new ArrayList();
list2.add("str");
list2.add("1234"); // 어차피 String인 요소만 들어감
list2.add("4.5");
String str3 = list2.get(1);
String str4 = list2.get(2);
→ 제네릭 사용 후 : 요소를 찾아올 때 타입 변환을 할 필요가 없음!
제네릭 타입 (class<T>, Interface<T>)
제네릭 타입은 타입을 파라미터로 가지는 클래스와 인터페이스
public class 클래스명<T> { ... }
public interface 인터페이스명<T> { ... }
일반적으로 타입 파라미터는 T로 표현
ex)
package chapter09;
public class Box<T> {
private T object;
public T get() {
return object;
}
public void set(T object) {
this.object = object;
}
}
→ Box.java
package chapter09;
public class BoxExample {
public static void main(String[] args) {
Box box = new Box();
box.set("string");
// String str = (String) box.get();
Box<Integer> integerBox = new Box<>();
integerBox.set(1234);
Integer integer = integerBox.get();
System.out.println(integer);
Box<String> stringBox = new Box<>();
stringBox.set("123문자열");
String str = stringBox.get();
System.out.println(str);
}
}
→ BoxExample.java
이렇게 제네릭은 클래스를 설계할 때 구체적인 타입을 명시하지 않고, 타입 파라미터로 대체함. 그리고 실제 클래스가 사용될 때 구체적인 타입을 지정함으로써 타입 변환을 최소화시킴!!
Weekly Quiz
https://github.com/drinkgalaxy/Ormi-Task/tree/main/WeeklyQuiz/week3
'Back-End > Java # 교육' 카테고리의 다른 글
[Java 교육] Collection/List/Set/Map (0) | 2024.02.15 |
---|---|
[Java 교육] 제한된 타입/와일드카드 타입/제네릭 상속, 구현 (1) | 2024.02.14 |
[Java 교육] 사용자 정의 예외/트랜잭션 (1) | 2024.02.07 |
[Java 교육] 예외처리/trycatch&finally (1) | 2024.02.06 |
[Java 교육] 오버라이딩/인터페이스/다형성 (1) | 2024.02.05 |