예외전달
: 예외가 발생된 명령의 메소드에서 발생된 예외를 직접 처리하지 않고, 발생된 예외를 '메소드를 호출한 명령' 으로 전달하는 것
형식) 접근제한자 반환형 메소드명(자료형 매개변수,...) 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
}
}