-
3-4 자바의 기초(ch8,9)카테고리 없음 2022. 10. 31. 19:02
Chapter 8
#8-1~3
프로그램 오류
-컴파일 에러(compile-time error) : 컴파일 할 때 발생하는 에러
-런타임 에러(runtime error) : 실행할 때 발생하는 에러
=>java의 런타임 에러
(1)에러(error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류
(2)예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
(에러(error)는 어쩔 수 없지만, 예외(exception)는 처리하자)
-논리적 에러(logical error) : 작성 의도와 다르게 동작
-예외처리의 정의와 목적
=>예외처리의 정의 : 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
=>예외처리의 목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것
#8-4~6
예외 처리하기. try-catch문
try{ //예외가 발생할 가능성이 있는 문장들을 넣는다 } catch (Exception1 e1) { //Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. } catch (Exception2 e2) { //Exception2이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. } catch (ExceptionN eN) { //Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다. }
#8-7,8
printStackTrace()와 getMessage()
PrintStackTrace() : 예외발생 당시의 호출스택(Call Stack)에 있었던 메서드의 정보와 예외 메시지를 화면에 출력한다.
getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
#8-9,10
예외 발생시키기
1. 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음
=> Exception e- new Exceoption("고의로 발생시켰음");
2. 키워드 throw를 이용해서 예외를 발생시킨다.
=> throw e;
checked예외, unchecked예외
-checked예외 : 컴파일러가 예외 처리 여부를 체크(예외 처리 필수)
-unchecked예외 : 컴파일러가 예외 처리 여부를 체크 안함(예외 처리 선택)
#8-11~14
메서드에 예외 선언하기
-예외를 처리하는 방법 : try-catch문, 예외 선언하기
-메서드가 호출시 발생가능한 예외를 호출하는 쪽에 알리는 것
(예외를 발생시키는 키워드 throw와 예외를 메서드에 선언할 때 쓰이는 throws를 잘 구별!)
void method( ) Exception1, Exception2, ... ExceptionN { // 메서드의 내용 } // method( )에서 Exception과 그 자손 예외 발생 가능 void method( ) throws Exception{ // 메서드의 내용 }
ex)
static void startInstall() throws SpaceException, MemoryException { if(!enoughSpace)) // 충분한 설치 공간이 없으면.. throw new SpaceException("설치할 공간이 부족합니다."); if (!enoughMemory()) // 충분한 메모리가 없으면.. throw new MemoryException("메모리가 부족합니다."); } //↑startInstall메서드의 끝
finally블럭
-예외 발생여부와 관계없이 수행되어야 하는 코드를 넣는다.
try{ // 예외가 발생할 가능성이 있는 문장들을 넣는다. } catch (Exception1 e1) { // 예외처리를 위한 문장을 적는다. } finally { // 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 넣는다. // finally블럭은 try-catch문의 맨 마지막에 위치해야한다. }
(try블럭 안에 return문이 있어서 try블럭을 벗어나갈 때도 finally 블럭이 실행된다.)
-주로 코드의 중복을 막기 위해 사용이 됨.
#8-15~17
사용자 정의 예외 만들기
-우리가 직접 예외 클래스를 정의할 수 있다.
-조상은 Exception과 RuntimeException중에서 선택
ex)
class MyException extends Exception { MyException(String msg) { // 문자열을 매개변수로 받는 생성자 super(msg); // 조상인 Exception클래스의 생성자를 호출한다. } }
예외 되던지기(exception re-throwing)
-예외를 처리한 후에 다시 예외를 발생시키는 것
-호출만 메서드와 호출된 메서드 양쪽 모두에서 예외처리하는 것
(왜 양쪽에서 처리? )
#8-18
연결된 예외(chained exception)
-한 예외가 다른 예외를 발생시킬 수 있다.
-예외 A가 예외 B를 발생시키면, A는 B의 원인 예외(cause exception)
Throwable initCause(Throwable cause) : 지정한 예외를 원인 예외로 등록
Throwable getCause : 원인 예외를 반환
public class Throwable implements Serializable { ... private Throwable cause = this; // 객체 자신(this)을 원인 예외로 등록 ... public synchronized Throwable initCause(Throwable cause) { this.cause = cause; // cause를 원인 예외로 등록 return this; } ... }
ex)
void install() throws InstallException { try { startInstall(); // SpaceException 발생 copyFiles(); } catch (SpaceException e) { InstallException ie = new InstallException("설치중 예외발생"); // 예외 생성 ie.initCause(e); // InstallException의 원인 예외를 SpaceException으로 지정 throw ie; // InstallException을 발생시킨다. } catch (MemoryException me) { ... } ... }
-연결된 예외를 사용하는 이유?
[이유1]여러 예외를 하나로 묶어서 다루기 위해
[이유2]checked예외를 unchecked예외로 변경하려 할 때
Chapter9
#9-1
Object클래스
-모든 클래스의 최고 조상. 오직 11개의 메서드만을 가지고 있다.
-notify(), wait() 등은 쓰레드와 관련된 메서드이다.
(Object클래스의 11개 각각 메서드 별 설명은 영상 참고 00:30)
equals(Object obj)
-객체 자신(this)과 주어진 객체(obj)를 비교한다. 같으면 true, 다르면 false
public boolean equals(Object obj) { return (this==obj); } ↑주소비교
equlas(Object obj)의 오버라이딩
-인스턴스 변수(iv)의 값을 비교하도록 equlas()를 오버라이딩해야 한다.
#9-4~6
hashCode()
-객체의 해시코드(hash code)를 반환하는 메서드
-Object클래스의 hashCode()는 객체의 주소를 int로 변환해서 반환
public class Object { ... public native int hashCode () ; }
-equals()를 오버라이딩하면, hashCode()도 오버라이딩해야 한다.
=>equals()의 결과가 true인 두 객체의 해시코드는 같아야 하기 때문.
-System.identityHashCode(Object obj)는 Object클래스의 hashCode()와 동일
toString(), toString()의 오버라이딩
-toString() : 객체를 문자열(String)으로 변환하기 위한 메서드
public String toString() { return getClass().getName()+"@"+integer.toHexString(hashCode()); }
#9-7~10
String클래스 (<-문자열을 다루기 위한 클래스)
-String클래스 = 데이터(char[]) + 메서드(문자열 관련)
-내용을 변경할 수 없는 불변(immutable) 클래스 **
=>덧셈 연산자(+)를 이용한 문자열 결합은 성능이 떨어짐.
문자열의 결합이나 변경이 잦다면, 내용을 변경가능한 StringBuffer를 사용
문자열의 비교
-String str = "abc";와 String str = new String("abc");의 비교
String str1 = "abc"; // 문자열 리터럴 "abc"의 주소가 str1에 저장됨 String str2 = "abc"; // 문자열 리터럴 "abc"의 주소가 str2에 저장됨 String str3 = new string("abc"); // 새로운 String 인스턴스를 생성 String str4 = new string("abc"); // 새로운 String 인스턴스를 생성
문자열 리터럴
-문자열 리터럴은 프로그램 실행시 자동으로 생성된다.(constant pool에 저장)
-같은 내용의 문자열 리터럴은 하나만 만들어진다.
빈 문자열("", empty string)
-내용이 없는 문자열. 크기가 0인 char형 배열을 저장하는 문자열
String str = ""; // str을 빈 문자열로 초기화
-크기가 0인 배열을 생성하는 것은 어느 타입이나 가능
char[] chArr = new char[0]; // 길이가 0인 char배열 int[] iArr = {}; // 길이가 0인 int배열
-문자(char)와 문자열(String)의 초기화
String s = null; char c = '\u0000';
보다
String s = ""; // 빈 문자열로 초기화 char c = ' '; // 공백으로 초기화
로 쓰는게 더 좋은 코드!
#9-11
String클래스의 생성자와 메서드(1/5)
(표는 양이 많기에 영상강의 참조)
#9-12~14
join()과 StringJoiner
-join()은 여러 문자열 사이에 구분자를 넣어서 결합한다.
String animals = "dog, cat, bear"; String[] arr = animals.split(","); // 문자열을 ','를 구분자로 나눠서 배열에 저장 String str = String.join("-",arr); // 배열의 문자열을 '-'로 구분해서 결합 System.out.println(str); // dog-cat-bear
문자열과 기본형 간의 변환
-숫자를 문자열로 바꾸는 방법
int i = 100; String str1 = i + ""; // 100을 "100"으로 변환하는 방법1 String str2 = String.valueOf(i); // 100을 "100"으로 변환하는 방법2
-문자열을 숫자로 바꾸는 방법
int i = Integer.parseInt("100"); // "100"을 100으로 변환하는 방법1 int i2 = Integer.valueOf("100"); // "100"을 100으로 변환하는 방법2 Integer i2 = Integer.valueOf("100"); // 원래는 반환 타입이 Integer
#9-15
StringBuffer클래스
-String처럼 문자형 배열(char[])을 내부적으로 가지고 있다.
형태:
public final class StringBuffer implements java.io.Serializable{ private char[] value; ... }
-그러나 String과 달리 내용을 '변경할 수 있다.'(mutable)
StringBuffer의 생성자
-배열은 길이 변경불가. 공간이 부족하면 새로운 배열 생성해야 한다.
-StringBuffer는 저장할 문자열의 길이를 고려해서 적절한 크기로 생성해야 한다.
StringBuffer의 변경
-StringBuffer는 String과 달리 내용 변경이 가능
=>
StringBuffer sb = new StringBuffer("abc"); sb.append("123"); // sb의 내용 뒤에 "123"을 추가한다.
-append()는 지정된 내용을 StringBuffer에 추가 후, StringBuffer의 참조를 반환
=>
StringBuffer sb2 = sb.append("ZZ"); // sb의 내용뒤에 "ZZ"를 추가한다. System.out.println(sb); // abc123ZZ System.out.println(sb2); // abc123ZZ
StringBuffer의 비교
-StringBuffer는 equals()가 오버라이딩되어 있지 않다.(주소비교를 해야함)
ex)
StringBuffer sb = new StringBuffer("abc"); StringBuffer sb2 = new StringBuffer("abc"); System.out.println(sb==sb2); // false System.out.println(sb.equals(sb2));; // false
이렇게 나오기 때문에
-StringBuffer를 String으로 변환 후에 equals()로 비교해야 한다.
=>
String s = sb.toString(); // sb를 String으로 변환 String s = sb2.toString(); System.out.println(s.equals(s2)); // true
#9-19,20
StringBuffer의 생성자와 메서드
(표를 설명하는 강의기에 강의영상 참조)
#9-21~24
StringBuilder
-StringBuffer는 동기화되어 있다. 멀티 쓰레드에 안전(thread-safe)('동기화' : 멀티 쓰레드에 안전하게 하는 것)
( 싱글 쓰레드 : 한번에 1개의 작업만 하는 것 (여태껏 한게 전부 싱글 쓰레드)
<
멀티 쓰레드 : 한번에 n개의 작업을 하는 것
예시로, 카카오톡의 경우에
싱글 쓰레드는 파일을 다운로드 받으면서 대화가 불가능. =>파일 다운로드 작업을 하느라, 동시 진행 불가
멀티 쓰레드는 파일을 다운로드 받으면서 대화가 가능. => 파일 다운로드, 메시지 전송 등 동시 진행이 가능
)
-멀티 쓰레드 프로그램이 아닌 경우, 동기화는 불필요한 성능저하를 초래.
(그렇기에, 작업이 1개만 수행되는 프로그램의 경우엔 싱글 쓰레드, 즉 StringBuffer 대신 StringBuilder를 쓰면 성능 향상!)
Math클래스
-수학관련 static메서드의 집합
public static final double E = 2.7182818284590~~ // 자연로그의 밑 public static final double PI = 3.14159265~~~ // 원주율
-round()로 원하는 소수점 아래 세 번째 자리에서 반올림하기
1.원래 값에 100을 곱한다.
90.7552 * 100 -> 9075.52
2.위의 결과에 Math.round()를 사용한다.
Math.round(9075.52) -> 9076
3.위의 결과를 다시 100.0으로 나눈다.
9076 / 100.0 -> 90.76 // double
9076 / 100 -> 90 // int
-그 외 메서드 관련 설명은 강의영상 참조(표)
#9-25~27
래퍼(wrapper) 클래스 <-기본형값을 감싸는 클래스
-8개의 기본형을 객체로 다뤄야할 때 사용하는 클래스
형태:
public final class Integer extends Number implements Comparable { ... private int value; ... ↑기본형(int)을 감싸고 있음. }
-그 외 각 기본형에 맞는 래퍼클래스,생성자,활용예 는 강의영상의 표 참조
Number클래스
-모든 숫자 래퍼 클래스의 조상.
#9-28~31
문자열을 숫자로 변환하기
-문자열을 숫자로 변환하는 다양한 방법
int i = new Integer("100").intValue(); // floatValue(), longValue(), ... int i2 = Integer.parseInt("100"); // 주로 이 방법을 많이 사용 Integer i3 = Integer.valueOf("100");
-n진법의 문자열을 숫자로 변환하는 방법
int i4 = Integer.parseInt("100",2); // 100(2) -> 4 int i5 = Integer.parseInt("100",8); // 100(8) -> 64 int i6 = Integer.parseInt("100",16); // 100(16) -> 256 int i7 = Integer.parseInt("FF",16); // FF(16) -> 255 // int i8 = Integer.parseInt("FF"); // NumberFormatException발생
오토박싱 & 언박싱
-기본형과 참조형간의 연산이 가능하도록 만듬(JDK1.5 이전엔 불가능이었음)
int i = 5; Integer i0bj = new Integer(7); int sum = i + i0bj; // 에러. 기본형과 참조형 간의 덧셈 불가(JDK1.5 이전)
-기본형의 값을 객체로 자동변환 하는 것을 오토박싱, 그 반대는 언박싱
ArrayList<Integer> list = new ArrayList<Integer>(); list.add(10); // 오토박싱. 10 -> new Integer(10) int value = list.ger(0); // 언박싱. new Integer(10) -> 10