본문 바로가기

학원/복기

0414 - 예외전달, Java API, System클래스, String클래스

예외전달

: 예외가 발생된 명령의 메소드에서 발생된 예외를 직접 처리하지 않고, 발생된 예외를 '메소드를 호출한 명령' 으로 전달하는 것 

형식) 접근제한자 반환형 메소드명(자료형 매개변수,...) throws 예외클래스. 예외클래스,...{ }

 

 예외가 전달되는 메소드를 호출한 명령에서 예외 처리

 

package xyz.itwill.exception;

public class ExceptionThrowsApp {
	//정적 메소드 >> 객체 생성하지 않고 클래스로 호출
	public static void display() throws ArrayIndexOutOfBoundsException { //예외전달
		int[] array = {10,20,30,40,50};
		
		for(int i=0;i<=array.length;i++) { //실행 예외 
			System.out.println("array[" + i + "] = " + array[i]);
		}
	}
	
	public static void main(String[] args) {
		//예외가 발생되어 전달되는 메소드를 호출한 명령에서 해당 예외 처리하는 것을 권장 	
		try {
		//ExceptionThrowsApp.display();//정적메소드는 클래스를 이용하여 호출 가능 
		display();//같은 클래스의 정적메소드는 클래스 표현 없이 메소드 호출 
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("[에러]프로그램에 예기치 못한 오류가 발생되었습니다.");
		}
	}
}

 

//출력결과
array[0] = 10
array[1] = 20
array[2] = 30
array[3] = 40
array[4] = 50
[에러]프로그램에 예기치 못한 오류가 발생되었습니다.

 

예외전달 예시1) 키보드로 정수값 2개를 입력받아 첫번째 정수값으로 두번째 정수값을 나눈 몫을 계산하여 출력하는 프로그램 작성 

package xyz.itwill.exception;

import java.util.InputMismatchException;
import java.util.Scanner;


public class CalcApp { 
	//생성자 
	public CalcApp() throws InputMismatchException, ArithmeticException {
		Scanner scanner = new Scanner(System.in);
		
		System.out.print("첫번째 정수값 입력 >> ");
		//Scanner.nextInt() : 입력값을 정수값으로 변환하여 반환하는 메소드 
		// => 문제: 입력값이 정수값으로 변환되지 못할 경우 InputMismatchException 발생 
		// => 직접 예외를 처리하지 않고 메소드를 이용하여 예외 전달 
		int num1 = scanner.nextInt();
		
		System.out.print("두번째 정수값 입력 >> ");
		int num2 = scanner.nextInt();
		
		//어떤 수를 0으로 나눈 경우 ArithmeticException 발생 
		// => 직접 예외를 처리하지 않고 메소드를 이용하여 예외 전달 
		System.out.println("[결과]" + num1 + " / " + num2 + " = " + (num1/num2));
		
		scanner.close();
	}
}

 

catch 사용해 예외처리

 

1) catch로 예외 하나씩 잡는 방법  (더 권장하는 방법-어떤 예외인지 명확히 알 수 있기 때문이다)

package xyz.itwill.exception;

import java.util.InputMismatchException;
import java.util.Scanner;

public class CalcApp {
    public static void main(String[] args) {
            try{
                //new 연산자로 클래스의 생성자를 호출하여 객체 생성 - 생성자에 작성된 명령 실행된다는 의미
                // => 생성자를 호출하면 예외가 전달되므로 예외처리를 해줘야 한다
                new CalcApp();
            } catch (InputMismatchException e) {
                System.out.println("[에러]정수값만 입력 가능합니다.");
            } catch (ArithmeticException e) {
                System.out.println("[에러]0으로 나눌 수 없습니다.");
            } catch (Exception e) { //Exception 클래스 : 모든 예외 관련 객체를 전달받아 예외처리할 수 있도록 해준다 
                System.out.println("[에러]프로그램에 예기치 못한 오류가 발생되었습니다.");
            }
}

 

2) 예외를 한꺼번에 잡는 방법 
: catch 구문에서 예외클래스를 [| 연산자]로 연결하여 다수의 예외클래스에 대한 객체를 전달받아 예외처리 가능 

package xyz.itwill.exception;

import java.util.InputMismatchException;
import java.util.Scanner;

public class CalcApp {
    public static void main(String[] args) {
            try{
                new CalcApp();
            } catch (InputMismatchException  | ArithmeticException e ) {
                System.out.println("[에러]형식에 맞는 값을 입력해 주세요.");		
            } catch (Exception e) { 
                System.out.println("[에러]프로그램에 예기치 못한 오류가 발생되었습니다.");
            }
	}
}

 

메소드에서 발생하는 모든 예외 전달 가능 >> 권장하진 않는다

public CalcApp() throws Exception { //메소드에서 발생되는 모든 예외를 전달 >> 권장하지 X
 ...
}

인위적으로 예외객체를 생성하여 예외를 발생시키는 명령 

형식) throw new 예외클래스(String message);

예외전달 예시2) 키보드로 정수값을 입력받아 저장된 비밀번호와 비교하여 비교결과를 출력하는 프로그램

프로그램 개발자가 직접 선언한 예외클래스 

package xyz.itwill.exception;

//예외클래스는 반드시 Exception 클래스를 상속받아 작성해야 한다 
public class PasswordMismatchException extends Exception {
	private static final long serialVersionUID = 1L; //경고 없애려고 작성한것 (추후 입출력때 배움)
	
	public PasswordMismatchException() {
		
	}
	
	public PasswordMismatchException(String message) {
		//Exception 클래스에는 예외 메세지를 저장하기 위한 필드가 존재한다.
		//=> super 키워드로 Exception 클래스의 매개변수가 있는 생성자를 호출하여 예외
		//메세지를 Exceiption 클래스 필드에 저장 
		super(message); //부모클래스(Exception)의 생성자 호출
	}
	
}

 

직접 만든 예외클래스로 예외처리

package xyz.itwill.exception;

import java.util.InputMismatchException;
import java.util.Scanner;

public class PasswordMatchApp {
	public static void main(String[] args) {
	
		int password = 123456;
		
		Scanner scanner = new Scanner(System.in);
		
		try {
			System.out.print("비밀번호 입력 >> ");
			int number = scanner.nextInt();
			
			if(number != password) {
				//PasswordMismatchException 클래스는 개발자가 직접 생성한 예외클래스로
				//예외발생시 예외처리를 하지 않을 경우 에러 발생 - 일반 예외
				// => 예외가 발생되면 catch 구문으로 프로그램의 흐름이 이동 
				throw new PasswordMismatchException("[결과]입력된 비밀번호가 틀립니다.");
			}
			
			//예외가 발생되지 않은 경우 실행될 명령 
			System.out.println("[결과]입력된 비밀번호가 맞습니다.");
			
		} catch (InputMismatchException e) {
			System.out.println("[에러]숫자만 입력 가능합니다.");
		} catch (PasswordMismatchException e) {
			System.out.println(e.getMessage());
		} catch (Exception e) {
			System.out.println("[에러]프로그램에 예기치 못한 오류가 발생되었습니다.");
		} finally {
			scanner.close(); //예외와 상관없이 무조건 실행되도록 finally 내부에 작성 
		}
	}
}

 


Java API(Application Programming Interface) 

: 자바 프로그램 개발에 프로그램 기능을 제공하기 위한 도구
 라이브러리를 이용하여 배포된 Java 자료형(클래스, 인터페이스, 열거형)
 API 문서를 활용하여 Java 자료형에 대한 설명을 제공받아 사용 
 온라인 API 문서 : https://docs.oracle.com/en/java/javase/17/docs/api/index.html

• java.lang 패키지 : Java 프로그램 개발에 필요한 기본 자료형을 제공하는 패키지 

 java.lang 패키지의 자료형은 import 처리를 하지 않아도 접근이 가능하다 

• Object 클래스 : 모든 Java 클래스가 반드시 상속받는 부모클래스 
 모든 Java 클래스를 대신하여 사용할 수 있는 대표클래스 

• Math 클래스 : 수학 관련 기능을 메소드로 제공하는 클래스 
• Class 클래스 : 메모리(MethodArea)에 저장된 클래스(클래스 객체)관련 정보를 저장하기 위한 클래스

 


System 클래스 

: 표준 입출력 스트림을 제공하거나 시스템 관련 기능을 메소드로 제공하는 클래스 

- System 클래스는 생성자가 없다. 은닉화 되어있기 때문게 객체를 만들 수 없다. >> 클래스로 호출해야한다.

 

 

• System.in : Java에서 제공되는 표준 입력장치(키보드)에 대한 입력스트림(=입력객체)이 저장된 필드  
• System.out : Java에서 제공되는 표준 출력장치(모니터)에 대한 출력스트림(=출력객체)이 저장된 필드 
• System.exit(int status) : 프로그램을 강제로 종료하는 메소드 

 

 System.currentTimeMillis() 시스템의 현재 날짜와 시간에 대한 타임스템프를 반환하는 메소드 
- 타임스템프(TimeStamp) : 날짜와 시간을 정수값으로 표현하기 위해 만들어진 시간값  
 1970년 1월 1일 기준으로 1/1000초(1ms)당 1씩 증가된 정수값  
 날짜와 시간을 정수값으로 표현하여 연산(-)하기 위해 사용  

• System.gc() : 메모리를 청소하는 프로그램(Garbage Collector)을 실행하는 메소드 

 

예시) 명령이 실행되는 동안 걸린 실행시간 계산하는 프로그램

package xyz.itwill.lang;

import java.util.Scanner;

public class SystemApp { 
	public static void main(String[] args) {
		//System.in : Java에서 제공되는 표준 입력장치(키보드)에 대한 입력스트림(객체)이 저장된 필드  
		Scanner scanner = new Scanner(System.in);
		
		//System.out : Java에서 제공되는 표준 출력장치(모니터)에 대한 출력스트림(객체)이 저장된 필드 
		System.out.print("정수값 입력 >> ");
		int num = scanner.nextInt();
		
		if(num == 0) {
			System.out.println("[메시지]프로그램을 강제로 종료합니다.");
			//System.exit(int status) : 프로그램을 강제로 종료하는 메소드 
			System.exit(0); //0 >> 무조건 종료
		}
		
		long startTime = System.currentTimeMillis();
		
		for(int i = 1 ; i <= num ; i++) {
			System.out.println(i + "번째 실행되는 명령");
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("실행시간 = " + (endTime - startTime) + "ms" );
		
		System.gc();
		
		scanner.close();
	}
}

 

출력 예시 

 

 


String 클래스

: 문자열을 저장하기 위한 클래스
 String 객체에 저장된 문자열에 대한 다양한 기능을 메소드로 제공한다.
 String 객체는 문자열을 내부적으로 byte 배열로 처리하여 배열 요소에 문자를 하나씩 저장 

 

 

 

문자열을 " " 기호를 사용하여 표현하면 자동으로 메모리의 메소드영역(MethodArea)에 String 객체를 생성하여 String 객체에  문자열에 저장한다. 

 

public class StringApp {
	public static void main(String[] args) {
		String str1 = "ABC"; //String 객체를 생성하여 참조변수에 메모리 주소 저장
	} 
}

"ABC"는 '값' 이 아니라 'String 객체'이다. 따라서, str1에는 String 객체의 메모리 주소가 저장되는 것이다. 
→ 메모리의 메소드영역에는 동일한 문자열이 저장된 String 객체를 생성할 수 없다.

 

 

String.toString() 

String 객체에 저장된 문자열을 반환하는 메소드 

→ 참조변수를 출력할 경우 자동으로 toString() 메소드를 호출한다

public class StringApp {
	public static void main(String[] args) {
		String str1 = "ABC"; 
		
		System.out.println("str1.toString() = " + str1.toString()); //str1.toString() = ABC
		//참조변수를 출력할 경우 자동으로 toString() 메소드 호출 
		System.out.println("str1 = " + str1); //str1 = ABC
	}
}

 

" " 기호로 String 객체를 표현할 경우, 동일한 문자열의 String 객체는 생성하지 않고 기존에 생성된 String 객체를 재활용하여 사용한다.

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; //기존의 String 객체의 메모리 주소를 제공받아 변수에 저장 
    }
}

 

참조변수를 비교연산자로 비교할 경우 참조변수에 저장된 객체의 메모리 주소를 비교
 String 객체에 저장된 문자열을 비교하는 것이 아니라 String 객체의 메모리 주소를 비교하는 것이다.

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; 
    
    if(str1 == str2) {
		System.out.println("str1 변수와 str2 변수에 저장된 String 객체의 메모리 주소가 같습니다.");
	} else {
		System.out.println("str1 변수와 str2 변수에 저장된 String 객체의 메모리 주소가 다릅니다.");
	} 
	//str1 변수와 str2 변수에 저장된 String 객체의 메모리 주소가 같습니다.
    }
}

 

new 연산자로 생성자를 호출하여 String 객체를 생성하면 메모리의 힙영역(HeapArea)에 새로운 String 객체를 생성하여 사용한다.

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; 
   	String str3 = new String("ABC"); 
		
	if(str1 == str3) {
		System.out.println("str1 변수와 str3 변수에 저장된 String 객체의 메모리 주소가 같습니다.");
	} else {
		System.out.println("str1 변수와 str3 변수에 저장된 String 객체의 메모리 주소가 다릅니다.");
	} 
	//str1 변수와 str3 변수에 저장된 String 객체의 메모리 주소가 다릅니다.
    }
}

 

String.equals(String str) (중요)

 : String 객체에 저장된 문자열과 매개변수로 전달받은 문자열을 비교하여 다른 경우 [false]를 반환하고 같은 경우 [true]를 반환하는 메소드 
 비교 문자열이 영문자인 경우 대소문자를 구분하여 비교 

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; 
   	String str3 = new String("ABC"); 
    
	if(str1.equals(str3)) {
		System.out.println("str1 변수와 str3 변수에 저장된 String 객체의 문자열이 같습니다.");
	} else {
		System.out.println("str1 변수와 str3 변수에 저장된 String 객체의 문자열이 다릅니다.");			
	}
	//str1 변수와 str3 변수에 저장된 String 객체의 문자열이 같습니다.
    }
    
    //대소문자 구분을 한다.
	String str4 = "abc";
		
	if(str1.equals(str4)) {
		System.out.println("str1 변수와 str4 변수에 저장된 String 객체의 문자열이 같습니다.");
	} else {
		System.out.println("str1 변수와 str4 변수에 저장된 String 객체의 문자열이 다릅니다.");			
	}
	//str1 변수와 str4 변수에 저장된 String 객체의 문자열이 다릅니다.
}

 

String.equalsIgnoreCase(String str) 

: String 객체에 저장된 문자열과 매개변수로 전달받은 문자열을 비교하여 다른 경우 [false]를 반환하고 같은 경우 [true]를 반환하는 메소드

→ 비교 문자열이 영문자인 경우 대소문자를 구분하지 않고 비교 

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; 
   	String str3 = new String("ABC"); 
    String str4 = "abc";
   
   if(str1.equalsIgnoreCase(str4)) {
		System.out.println("str1 변수와 str4 변수에 저장된 String 객체의 문자열이 같습니다.");
	} else {
		System.out.println("str1 변수와 str4 변수에 저장된 String 객체의 문자열이 다릅니다.");			
	}
	//str1 변수와 str4 변수에 저장된 String 객체의 문자열이 같습니다.
    
}
}

 

• String.compareTo(String str)

: String 객체에 저장된 문자열과 매개변수로 전달받은 문자열을 비교하여 String 객체의 문자열이 큰 경우 양수를 반환하고 매개변수로 전달받은 문자열이 큰 경우 음수를 반환, 같은 경우 0를 반환하는 메소드 

 

→ 대소문자를 구분한다

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; 
   	String str3 = new String("ABC"); 
   	String str4 = "abc";
   
  if(str1.compareTo(str4) > 0) {
		System.out.println("str1 변수에 저장된 문자열이 str4에 저장된 문자열보다 큽니다.");
	} else if (str1.compareTo(str4) < 0) {
		System.out.println("str1 변수에 저장된 문자열이 str4에 저장된 문자열보다 작습니다.");			
	} else {
		System.out.println("str1 변수에 저장된 문자열이 str4에 저장된 문자열이 같습니다.");			
	}
	//str1 변수에 저장된 문자열이 str4에 저장된 문자열보다 작습니다. 
	//(소문자 > 대문자)
    
}
}

 

String.getBytes()  

: Stirng 객체에 저장된 문자열을 byte 배열로 변환하여 변환하는 메소드
 byte 배열의 요소에는 문자열을 구성하는 문자들이 코드값(정수값)으로 차례대로 저장 

(문자열을 구성하는 문자들을 하나씩 읽어들여 처리할 때 많이 사용한다)

 

public class StringApp {
	public static void main(String[] args) {
    	String str1 = "ABC"; 
	String str2 = "ABC"; 
   	String str3 = new String("ABC"); 
   	String str4 = "abc";
    
    	byte[] array = str1.getBytes();
	for(byte ch : array) {
		System.out.print((char)ch); //byte 배열의 요소값(정수)을 문자로 형변환하여 출력
	} 
       //ABC
}
}

 

String.length() 

: String 객체에 저장된 문자열의 문자 갯수를 반환하는 메소드

public class StringApp {
	public static void main(String[] args) {
    	String str5 = "ABCDEFG";
	//String.length() : String 객체에 저장된 문자열의 문자 갯수를 반환하는 메소드
	System.out.println("문자열의 문자 갯수 = " + str5.length());
	//문자열의 문자 갯수 = 7
    }
}

 

String.charAt(int index) 

: String 객체에 저장된 문자열에서 첨자(Index) 위치의 문자를 반환하는 메소드 

 

public class StringApp {
	public static void main(String[] args) {
    	String str5 = "ABCDEFG";
        
	System.out.println("두번째 위치의 문자 = " + str5.charAt(1));
	//두번째 위치의 문자 = B
    }
}

 

String.indexOf(String str) 

: String 객체에 저장된 문자열에서 매개변수로 전달받은 문자열(문자)을 처음부터 차례대로 검색하여 
시작위치값(첨자)를 반환하는 메소드 

 

public class StringApp {
	public static void main(String[] args) {
    	String str5 = "ABCDEFG";
        
	System.out.println("A 문자열의 저장 위치 =  " + str5.indexOf("A"));
	//A 문자열의 저장 위치 =  0
	System.out.println("EFG 문자열의 저장 위치 =  " + str5.indexOf("EFG"));
	//EFG 문자열의 저장 위치 =  4
		
	//=>매개변수로 전달받은 문자열을 찾을 수 없는 경우 -1 반환 
	System.out.println("A 문자열의 저장 위치 =  " + str5.indexOf("X"));
	//A 문자열의 저장 위치 =  -1
    }
}

 

• String.toUpperCase() / String.toLowerCase() 

String.toUpperCase() : String 객체에 저장된 문자열을 모두 대문자로 변환하여 반환하는 메소드

String.toLowerCase() : String 객체에 저장된 문자열을 모두 소문자로 변환하여 반환하는 메소드 

 

public class StringApp {
	public static void main(String[] args) {
    String str6 = "Java Programming";
		
	System.out.println("str6 = " + str6); //str6 = Java Programming
	System.out.println("str6 = " + str6.toUpperCase()); //str6 = JAVA PROGRAMMING
	System.out.println("str6 = " + str6.toLowerCase()); //str6 = java programming
    }
    }

 

• String.trim() 

: String 객체에 저장된 문자열에서 앞과 뒤에 존재하는 모든 공백을 제거하여 반환하는 메소드 

 

public class StringApp {
	public static void main(String[] args) {
    String str7 =  "         홍길동        ";
		
	System.out.println("입력된 이름은 [" + str7 + "]입니다."); //입력된 이름은 [         홍길동        ]입니다.
	System.out.println("입력된 이름은 [" + str7.trim() + "]입니다."); //입력된 이름은 [홍길동]입니다.
    }
}


• String.replace(String regEx, String replacement) 

: String 객체에 저장된 문자열에서 검색 문자열을 찾아 치환 문자열로 변경하여 반환하는 메소드 

- regEx : 검색문자열 - 정규표현식 

public class StringApp {
	public static void main(String[] args) {
    String str8 = "    임     꺽     정      ";
	System.out.println("입력된 이름은 [" + str8 + "]입니다."); 
	//입력된 이름은 [    임     꺽     정      ]입니다.
	
	System.out.println("입력된 이름은 [" + str8.replace(" ", "").replace("꺽","걱") + "]입니다."); 
	//공백제거 , 꺽->걱 
    	//입력된 이름은 [임걱정]입니다.
    }
}

 

• String.split(String regEx)

: String 객체에 저장된 문자열을 매개변수로 전달받은 문자열(정규표현식)로 구분 분리하여 문자열 배열로 반환하는 메소드

 

→ 정규표현식에서 사용되는 메타문자를 일반문자로 변환하여 사용하기 위해 [\\]를 사용하여 회피문자로 처리하여 표현
public class StringApp {
	public static void main(String[] args) {
    String str9 = "010-1234-5678";
    
    String[] numArray = str9.split("-");
	//String[] numArray = str9.split("\\*");  // *은 메타문자 >> 일반문자로 변환위해 \\ 사용해 회피문자로 처리해 표현 
	System.out.println("전화번호 앞부분 = " + numArray[0]); //전화번호 앞부분 = 010
	System.out.println("전화번호 중간부분 = " + numArray[1]); //전화번호 중간부분 = 1234
	System.out.println("전화번호 뒷부분 = " + numArray[2]); //전화번호 뒷부분 = 5678
    }
}

 

• String.substring(int beginIndex, int endIndex) 

: String 객체에 저장된 문자열에서 시작첨자(문자포함)에서 종료첨자(문자미포함)까지의 문자열을 분리하여 반환하는 메소드 
→ substring() 메소드 매개변수에 시작첨자만 전달하면 시작첨자의 문자로부터 문자열의 마지막 문자까지 분리하여 반환

 

public class StringApp {
	public static void main(String[] args) {
   	String str9 = "010-1234-5678";
    
   	System.out.println("전화번호 앞부분 = " + str9.substring(0,3));  //전화번호 앞부분 = 010
	System.out.println("전화번호 중간부분 = " + str9.substring(4,8)); //전화번호 중간부분 = 1234
	//System.out.println("전화번호 뒷부분 = " + str9.substring(9,13)); //전화번호 뒷부분 = 5678
		
	//substring() 메소드 매개변수에 시작첨자만 전달하면 시작첨자의 문자로부터 문자열의
	//마지막 문자까지 분리하여 반환 
	System.out.println("전화번호 뒷부분 = " + str9.substring(9)); //전화번호 뒷부분 = 5678
    }
}

 

• String.valueOf(Object obj) 

: 매개변수로 전달받은 모든 자료형(정수값, 실수값 등..)의 값을 문자열(String 객체)로 변환하여 반환하는 메소드 

 

public class StringApp {
	public static void main(String[] args) {
    	String numString = String.valueOf(100);
		
	//valueOf 보다 편한 방법
	//String numString = 100+""; // ""+값 또는 값+"" 형식으로 값을 문자열과 결합하여 문자열로 사용 가능 	
	System.out.println("numString = " + numString); //numString = 100
    }
}