일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- vscode
- Python
- MySQL
- 따옴표 삭제
- 에러
- php
- console창
- localhost
- jupyter
- error
- DataGrip
- 단축키
- run sql script
- 깃 토큰
- cmd
- visualstudio code
- database
- 오류
- Visual Studio Code
- 데이터베이스
- OrCAD 다운로드
- csv
- 클론
- github token
- 파이썬
- import data
- github clone
- clone
- error 해결
- PHPStorm
- Today
- Total
개발 노트
7/28 자바 클래스, StringBuffer, 자바 예외처리, try-catch-finally, throws, throw 본문
7/28 자바 클래스, StringBuffer, 자바 예외처리, try-catch-finally, throws, throw
hayoung.dev 2022. 7. 28. 20:48[9.자바 주요 클래스]
p. 9 자바 API Documentation : 자바 클래스들에 대한 도움말.
http://docs.oracle.com/javase/8/docs/api/index.html
Java Platform SE 8
docs.oracle.com
이 사이트의 자바 API Documentation에서 확인할 수 있다.
[ch09]
Homework01.java
package ch09;
/*과제, 두 개의 Method override해서 객체 조회하기
같다
같다
[x=1, y=2, z=3]
[x=1, y=2, z=5]
출력 결과 이렇게 나오게, 객체는 x, y만 비교.
*/
class Point3D {
int x,y,z;
public Point3D(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object obj) {
Point3D p = null;
boolean result = false;
if(obj instanceof Point3D) p = (Point3D) obj;
if(obj != null && this.x==p.x && this.y==p.y) result = true;
return result;
}
//@Override
//public String toString() {
// return super.toString();
//}
//toString이 오버라이딩 된 것이다. (@Override가 생략됨.)
//원래는 .toString을 쓰지 않으면 해시코드가 출력되는데, 오버라이딩을 통해 값을 출력함.
public String toString() {
return"[x="+x+", y="+y+", z=" +z+"]";
}
}
public class Homework01 {
public static void main(String[] args) {
Point3D pd1 = new Point3D(1, 2, 3);
Point3D pd2 = new Point3D(1, 2, 4);
Point3D pd3 = new Point3D(1, 2, 5);
if (pd1.equals(pd2)) System.out.println("같다");
else System.out.println("다르다");
if (pd1.equals(pd3)) System.out.println("같다");
else System.out.println("다르다");
System.out.println(pd1);
System.out.println(pd3);
//System.out.printf("[x=%d, y=%d, z=%d] \n", pd1.x, pd1.y, pd1.z);
//System.out.printf("[x=%d, y=%d, z=%d]", pd3.x, pd3.y, pd3.z);
}
}
출력 결과
[SprintBuffer 개념]
String에서 문자열을 붙이면 기존 문자는 GC(garbage collection)에 의해 사라지고 새로운 String 인스턴스가 생기는 것이므로 효율적이지 못하다. 하지만 고정적인 String 과는 반대로 StringBuffer/StringBuilder 는 가변성을 가지기 때문에 .append() .delete() 등의 API를 이용하여 동일 객체내에서 문자열을 변경하는 것이 가능하며 효율적이다. 따라서 문자열의 추가,수정,삭제가 빈번하게 발생할 경우라면 String 클래스가 아닌 StringBuffer / StringBuilder를 사용한다.
String : 문자열 연산이 적고 멀티쓰레드 환경일 경우
StringBuffer : 문자열 연산이 많고 멀티쓰레드 환경일 경우
StringBuilder: 문자열 연산이 많고 단일쓰레드이거나 동기화를 고려하지 않아도 되는 경우
StringBuffer01.java
package ch09;
public class StringBuffer01 {
public static void main(String[] args) {
StringBuffer strBuf = new StringBuffer();
int len = strBuf.length(); //length는 길이 즉 들어있는 공간. 실제로 들어가있는 공간
int size = strBuf.capacity(); //Capacity는 용량 즉 들어갈 수 있는 공간
System.out.println("1." + strBuf + " / " + len + " / " + size);
strBuf.append("누구든지 사랑하기 위해선 ");
//문자열이 들어갈 수록 알아서 공간을 늘려줌.
len=strBuf.length();
size=strBuf.capacity();
System.out.println("2." + strBuf + "/ " + len + " / " + size);
strBuf.append("한 번쯤 증오의 가슴이어야 했다."); //문자열 추가
len=strBuf.length();
size=strBuf.capacity();
System.out.println("3." + strBuf + " / " + len + " / " + size);
}
}
출력 결과
p.38 StringBuffer클래스의 생성자와 메서드 : 외우지 않음. 필요한 것 골라서 쓰기.
p.42 StringTokenizer : 쉼표로 구분해서 각각의 원소를 하나의 토큰으로 취급한다.
import java.util.StringTokenizer;
public class Ex13 {
public static void main(String[] args) {
StringTokenizer stok01=
new StringTokenizer("사과,바나나,귤,오렊지,키위", ",");
while(stok01.hasMoreTokens()) // 토큰이 있으면
System.out.println(stok01.nextToken());
// 차례대로 파싱된 문자열을 얻어온다.
}
}
StringTokenizer01.java
package ch09;
import java.util.StringTokenizer;
public class StringTokenizer01 {
public static void main(String[] args) {
StringTokenizer st = new StringTokenizer("산딸기, 집딸기,판딸기.집딸기,알카리딸기",".,");
StringTokenizer st2 = new StringTokenizer("산딸기, 집딸기,판딸기.집딸기,알카리딸기",",");
//.이 있으면 .도 기준으로 잘림. .이 없으면 ,기준으로만 잘림
//띄어쓰기도 포함됨
//while문은 토큰이 더 없으면 true에서 false로 알아서 바뀜
while(st.hasMoreElements()) { //.hasMoreElements는 있는지 물어보는 것.
System.out.println(st.nextElement()); //.nextElement는 가져오는 것.
}
System.out.println();
while(st2.hasMoreElements()) {
System.out.println(st2.nextElement());
}
}
}
출력 결과
System01.java
package ch09;
//시스템 환경을 살펴볼 수 있다.
public class System01 {
public static void main(String[] args) {
String path = System.getenv("path"); //env : 환경의 약자
String java_home = System.getenv("JAVA_HOME");
System.out.println(path);
System.out.println(java_home);
}
}
출력 결과
p.29 String class : String도 class이다.
문자열 상수를 생성자에 전달해서 String 객체를 생성한 예 : String str = new String(“java”);
String 객체에 문자열 리터럴을 저장 : String str = “java”;
String1.java
package ch09;
public class String1 {
public static void main(String[] args) {
String a1 = "Java"; //String 객체에 문자열 리터럴을 저장
String a2 = "Java"; //이미 존재하는 문자열이기 때문에 이 상수를 공유하게 된다.(주소가 같다)
String a3 = new String ("Java"); //문자열 상수를 생성자에 전달해서 String 객체를 생성
String a4 = new String ("java");
System.out.println(a1 + ", " + a2 + ", " + a3);
//== 연산자는 비교하고자 하는 대상의 주소값
if (a1 == a2) System.out.println("== a1과 a2는 같다");
else System.out.println("== a1과 a2는 다르다");
if (a1 == a3 ) System.out.println("== a1과 a3은 같다");
else System.out.println("== a1과 a3은 다르다");
//equals 메소드는 비교하고자 하는 대상의 내용 자체를 비교
if (a1.equals(a2)) System.out.println("equals a1과 a2는 같다");
else System.out.println("equals a1과 a2는 다르다");
if (a1.equals(a3)) System.out.println("equals a1과 a3은 같다");
else System.out.println("equals a1과 a3은 다르다");
if (a1.equals(a4)) System.out.println("a1과 a4는 같다");
else System.out.println("a1과 a4는 다르다");
//대소문자 무시
if (a1.equalsIgnoreCase(a4)) System.out.println("a1과 a4는 같다");
else System.out.println("a1과 a4는 다르다");
}
}
출력 결과
p.31 String클래스 - 생성자와 메서드 : 외울 필요 없음. 참조해서 사용하기.
String2.java
package ch09;
public class String2 {
public static void main(String[] args) {
char[] c = {'k', 'o', 'r', 'e', 'a'}; //문자 하나 단위를 char라고 한다. 문자배열.
String str1 = new String(c); //언어 만든 사람이 String을 생성자 오버로딩 해 둔것임.
System.out.println("str1->" + str1);
String str2 = new String("Fighting");
System.out.println("str2->" + str2);
String str3 = str1 + str2;
System.out.println("str3->" + str3);
System.out.println(2+1+1+5+"년"); //우선순위가 앞부터여서 연산을 한 뒤 "년" 출력
System.out.println("연1:" +2+1+1+5); //문자열이 앞에 있어서 계산되지 않고 그대로 붙여서 출력
System.out.println("연2:"+(2+1+1+5)); //계산을 하고 싶은 경우 괄호를 치면 우선순위가 먼저 되기 때문에 integer형으로 바뀌기 때문에 연산을 한 뒤 문자열과 함께 출력
}
}
출력 결과
String3.java
package ch09;
public class String3 {
public static void main(String[] args) {
String str = "15분 남았음";
for(int i = 0; i < str.length(); i++) {
System.out.print(str.charAt(i) + " ");
}
System.out.println();
for(int i = str.length()-1; i>=0; i--) {
System.out.print(str.charAt(i));
}
}
}
출력 결과
String5.java
package ch09;
public class String5 {
public static void main(String[] args) {
String fullName = "Hello.java";
int index = fullName.indexOf('.'); //.가 처음 나오는 인덱스 값(위치)을 물어보는 것.
System.out.println("index->"+index);
String fileName = fullName.substring(0, index); //0부터 index미만(index-1까지)
String ext = fullName.substring(index+1); //.substring은 값을 하나만 주는 경우에는 그 지점부터 끝까지 감. 많이 쓰임.
System.out.println(fullName+"의 확장자를 제외한 이름은 " + fileName);
System.out.println(fullName+"의 확장자는 " + ext);
}
}
출력 결과
[10. 자바 예외처리]
p.2 에러 유형
p.3 예외의 개요
1) 예외 : 프로그램 실행 중에 발생하는 예기치 않은 사건
2) 예외가 발생하는 예시
- 정수를 0으로 나누는 경우
- 배열의 첨자가 음수 또는 범위를 벗어나는 경우
- 부적절한 형변환이 일어나는 경우
- 입출력을 위한 파일이 없는 경우 등
3) 자바 언어는 프로그램에서 예외를 처리할 수 있는 기법을 제공
[ch10]
Exception1.java
package ch10;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Exception1 {
public static void main(String[] args) throws NumberFormatException, IOException {
//키보드에서 값을 읽어오면 InputStreamReader으로 읽어옴.
//BufferedReader는 연속된 글자 형태로 text를 읽어오는 객체. 이걸로 인스턴스 객체를 받아옴.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) { //오류가 발생하지 않으면 계속 실행
System.out.print("첫 번째 값을 입력하세요 => ");
//in.readline() 에러 나면 throws declaration로 코딩하여 exception 추가
//Integer.parseInt를 썼기 때문에 숫자로 입력하여야 오류가 나지 않음.
int num1 = Integer.parseInt(in.readLine());
System.out.print("두 번째 값을 입력하세요 => ");
int num2 = Integer.parseInt(in.readLine());
System.out.println(num1 + " / " + num2 + " = " + num1/num2);
//0으로 나눴을 때 나오는 예외 : ArithmeticException (알아두기)
}
}
}
출력 결과
예외 발생 : Exception in thread "main" java.lang.ArithmeticException: / by zero at ch10.Exception1.main(Exception1.java:21)
Exception2.java
package ch10;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Exception2 {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) { //오류가 발생하지 않으면 계속 실행
int num;
try {
System.out.println("첫 번째 값을 입력하세요 => ");
int num1 = Integer.parseInt(in.readLine());
System.out.print("두 번째 값을 입력하세요 =>");
int num2 = Integer.parseInt(in.readLine());
System.out.println(num1 + " / " + num2 + " = " + num1/num2);
} catch (Exception e) { //이렇게 하면 시스템이 오류가 났을 때 멈추지 않음.
System.out.println("값을 잘못 입력했습니다."+e.getMessage()); //getMessage()는 시스템에서 보여주는 메시지. (알아두기)
//System.out.println("0 나은 세상을 위해 노력하고 있습니다.");
//이렇게 하면 사용자에겐 오류가 나지 않은 것처럼 보이고 개발자들만 알 수 있음. 그래서 오류 처리가 중요함.
}
}
}
}
출력 결과
Exception3.java
package ch10;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Exception3 {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) { //오류가 발생하지 않으면 계속 실행
int num;
//try catch는 if문과 비슷함. catch가 있으면 그 catch만 실행, 없으면 다음 catch를 찾음.
try {
System.out.print("첫 번째 값을 입력하세요 => ");
int num1 = Integer.parseInt(in.readLine());
System.out.print("두 번째 값을 입력하세요 => ");
int num2 = Integer.parseInt(in.readLine());
System.out.println(num1 + " / " + num2 + " = " + num1/num2);
//예외 문구를 모를 때엔 오류가 나도록 입력해보고 예외처리 메시지를 복사해오면 됨.
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해야 합니다");
} catch (ArithmeticException e) {
System.out.println("0으로 나누면 안돼요");
} catch (Exception e) {
System.out.println("전체 오류");
}
}
}
}
출력 결과
ExceptionEx01.java
package ch10;
public class ExceptionEx01 {
public static void main(String[] args) {
int number = 100;
int result = 0;
for(int i = 0; i<10; i++) {
//100을 10미만의 숫자로 나눔.
//10미만의 숫자 중에 0도 포함되어 있기 때문에 랜덤의 숫자로 10번을 돌리는 동안 에러가 날 수도, 안날 수도 있어서 에러를 찾기 어렵다.
result = number / (int)(Math.random() * 10);
System.out.println(result);
}
}
}
출력 결과(에러가 안 난 경우)
출력 결과(에러가 난 경우)
Exception in thread "main" java.lang.ArithmeticException: / by zero at ch10.ExceptionEx01.main(ExceptionEx01.java:11)
ExceptionEx02.java
package ch10;
//ExceptionEx01.java 예외처리
public class ExceptionEx02 {
public static void main(String[] args) {
int number = 100;
int result = 0;
for(int i = 0; i<10; i++) {
try {
result = number / (int)(Math.random() * 10);
System.out.println(result);
} catch (ArithmeticException e) { //0으로 나와서 exception 발생하면
System.out.println("0");
}
}
}
}
출력 결과 : 0이 있어도 오류가 나서 멈추지 않고 그대로 0이 출력된다.
ExceptionEx03.java
package ch10;
public class ExceptionEx03 {
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
System.out.println("main메서드에서 예외가 처리");
}
}
static void method1() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("method1메서드에서 예외가 처리");
throw e;
}
}//method1메서드의 끝
}
출력 결과
ExceptionTest.java
package ch10;
public class ExceptionTest {
//3. 해당 클래스가 없으면 ClassNotFoundException가 발생하여 이 예외를 호출한 곳(main함수)으로 넘김(throw)
//만약 class를 찾으면 throws는 실행이 되지 않음.
static void callDriver() throws ClassNotFoundException {
Class.forName("oracle.jdbc.driver.OracelDriver"); //2. "oracle.jdbc.driver.OracelDriver"클래스 가져옴(드라이브 설치)
System.out.println("완료");
}
public static void main(String[] args) {
try {
callDriver(); //1. callDriver 함수를 실행시킨다.
} catch (ClassNotFoundException e) { //4. ClassNotFoundException 예외를 잡아서 catch문 실행. 이게 실행되면 "완료"는 출력되지 않음. 바로 끝나기 때문.
System.out.println("클래스를 찾을 수 없습니다.");
} catch (Exception e) {
System.out.println(e.getMessage());
} finally { //5. 오류가 나든 안나든 무조건 실행
System.out.println("시스템 종료.");
}
}
}
출력 결과
p.6 예외 관련 클래스
자바는 예외를 객체로 취급한다. 예외 관련 클래스를 java.lang 패키지에서 제공한다. 자바 프로그램에서는 Error, RuntimeException 클래스의 하위 클래스들을 제외한 모든 예외를 처리하여야 한다. 일반적으로 Error, RuntimeException 클래스(하위 클래스 포함) 들과 연관된 예외는 프로그램에서 처리하지 않는다. 예외를 처리하여 얻는 이득보다 예외를 처리하기 위한 노력이 너무 크기 때문이다.
자주 발생하는 이정도 예외만 알아두면 됨. 다 알아둘 필요 없음.
- NoSuchMethodException : 메소드가 존재하지 않을 때
- ClassNotFoundException : 클래스가 존재하지 않을 때
- ArithmeticException : 0으로 나누는 등의 산술적인 예외
- NegativeArraySizeException : 배열의 크기를 지정할 때 음수의 사용
- NullPointerException : null 객체의 메소드나 멤버 변수에 접근할 때
- IndexOutOfBoundException : 배열이나 스트링의 범위를 벗어난 접근 : 하위클래스로 ArrayIndexOutOfBoundsException 클래스와 StringIndexOutOfBoundsException 클래스를 제공
p.8 예외를 처리하는 방법
1. 예외가 발생한 메소드 내에서 직접 처리 (try-catch-finally)
try {
예외 발생 가능성이 있는 문장들;
} catch(예외타입1 매개변수명) {
예외타입1의 예외가 발생할 경우 처리 문장들;
} catch(예외타입2 매개변수명) {
예외타입2의 예외가 발생할 경우 처리 문장들;
//finally는 필수는 아니지만 파일 close(메모리 절감을 위해 close하는게 좋음)와 같이
//오류가 나도 실행해야 하는 게 있을 때 사용함.
} finally {
항상 수행할 필요가 있는 문장들;
}
2. 예외가 발생한 메소드를 호출한 곳으로 예외의 객체 넘겨줌 (throws)
3. 사용자 정의 예외 생성 (throw)
1) 기존의 예외 클래스로 예외를 처리할 수 없다면 사용자만의 예외 클래스를 작성하여 발생시킬 수 있다. 사용자가 예외 클래스를 정의하려면 예외 클래스의 최상위 클래스인 java.lang.Exception 클래스를 상속받아 클래스를 정의한다.
class 예외 클래스 이름 extends Exception
2) 자바 가상 머신은 프로그램 수행중에 예외가 발생하면 자동으로 해당하는 예외 객체를 발생시킨 다음 catch 블록을 수행한다. 하지만 예외는 사용자가 강제적으로 발생시킬 수도 있다. 자바는 예외를 발생시키기 위해 throw 예약어를 사용한다.
throw new 예외 클래스 이름(매개변수);
throw를 이용한 예외 발생시에도 try-catch-finally 구문을 이용한 예외 처리를 하거나, throws를 이용하여 예외가 발생한 메소드를 호출한 다른 메소드로 넘기는 예외 처리 방법을 사용해야 한다.
Throw1.java
package ch10;
public class Throw1 {
public static void main(String[] args) {
System.out.println("안녕");
Exception e1 = new Exception("내가 Error 만들었다");
try {
throw e1;
//System.out.println("이건 안 출력");
//여기에 해당되면 e1이 e2가 된다.
} catch(Exception e2) { //Exception은 시스템에 관련된 에러들을 다 갖고 있음.
System.out.println("e2 Exception -->" + e2.getMessage() + "kkk");
}
System.out.println("프로그램이 정상 종료되었음.");
}
}
출력 결과
Exception5.java
package ch10;
public class Exception5 {
static void method(boolean b) { //24줄이 static이니까 이것도 static이어야 함.
try {
System.out.println(1 + "b-->" + b);
//if문은 1줄만 쓰는 경우에 중괄호를 생략할 수 있다.
//즉 2줄인데 중괄호가 생략돼있다면 두 번째 줄은 else문인 것이다...(else가 생략되어 있는 것)
if(b) throw new ArithmeticException(); //ArithmeticException로 던짐
System.out.println(2); //false일때 실행됨.
//예외가 발생하면 실행되지 않는 문장
} catch(RuntimeException r) {
System.out.println("RuntimeException" + "--> " + 3);
return;
//메서드를 빠져나간다.(finally블럭을 수행한 후에) (함수 끝남.)
} catch(Exception e) {
System.out.println(4);
return;
} finally {
//예외발생여부에 관계없이 항상 실행되는 문장
System.out.println("예외발생여부에 관계없이 항상 실행되는 문장" + 5);
}
//return이 실행되면 try catch문만 빠져나가는 게 아니라 함수를 빠져나가기 때문에 이부분 실행되지 않음
System.out.println("정상적으로 끝나야 실행되는 문장");
}
public static void main(String[] args) {
method(true);
method(false);
}
}
모르고 넘어갈 수 있는 내용! ArithmeticException가 없으면 바로 위 조상인 RuntimeException으로 가게 된다.(ctrl + T로 확인)
출력 결과
Exception7.java
package ch10;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Exception7 {
public static void main(String[] args) {
FileReader reader;
char[] buffer = new char[100];
String file_name = ".classpath"; //.classpath라는 이름을 가진 파일을 읽어들인다.
//String file_name = ".classpathkkk"; // 이렇게 하면 그런파일 없슴당 출력됨.
try {
reader = new FileReader(file_name);
reader.read(buffer,0,100); //문자를 읽어서 buffer 변수로 넣는다. 100바이트를 읽음.
String str = new String(buffer); //buffer를 읽으면 str로(string 객체로 바꿔놓으면 조작하기가 편하기 때문)
System.out.println("읽은 건 " + str);
reader.close();
} catch(FileNotFoundException e) {
System.out.println("그런 파일 없슴당");
} catch(IOException e) {
System.out.println("읽다가 에러났음");
} finally {
System.out.println("어쨌거나 읽었어요");
}
}
}
출력결과
출력 결과는 100바이트임.