본문 바로가기
Programming Language/Java

[국비] Java 내용정리 Day15

by tpleehan 2021. 11. 25.

예외를 강제로 발생시키는 키워드 throw

  • 메서드나 생성자 실행 도중에 throw 키워드를 만나면 즉시 throw로 생성한 예외가 발생한다.
  • 예외가 발생되면 실행되던 코드는 즉시 중단되고 예외를 처리할 수 있는 catch문으로 바로 이동하게 된다.
  • 적절히 활용하면 void가 아닌 메서드를 강제로 종료시킬 때 사용된다. 또한, 에러 상황이 아니지만 프로그램 실행에 적절치 못한 상황에서 코드의 흐름을 바꿔 줄 수가 있다.
  • 기존에 정의된 예외 클래스 외에 필요에 따라 개발자가 새로운 예외 클래스를 정의해서 사용할 수 있다.
  • 대부분의 경우 Exception을 상속받아서 클래스를 디자인한다.
package exception.throw_;

public class ThrowExample {

	static int calcTotal(int num) throws Exception {

		if(num <= 0) {
			// 이 시점에서 강제로 예외를 발생 시킨다.
			throw new Exception();
		}
		
		int total = 0;
		for (int i = 1; i <= num; i++) {
			total += i;
			
		}
		return total;
	}
	
	public static void main(String[] args) {
		
		try {
			System.out.println(calcTotal(100));
			System.out.println(calcTotal(-120));
		} catch (Exception e) {
			System.out.println("매개값을 양수로 주세요.");
		}

	}

}
package exception.myexception;

public class Calculator {

	public int left;
	public int right;
	
	public void setOperand(int left, int right) {
		this.left = left;
		this.right = right;
	}

	public void divide() throws DivideException {
		if (this.right == 0) {
			throw new DivideException("0으로 나눌 수 없습니다.", 10);
		}
		System.out.println(this.left / this.right);
	}
	
}
package exception.myexception;

public class DivideException extends Exception {

	private final int errCode;
	
	public DivideException(String message, int code) {
		super(message);
		errCode = code;
	}
	
	public int getErrCode() {
		return errCode;
	}
	
}
package exception.myexception;

public class MainClass {

	public static void main(String[] args) {
		
		Calculator c = new Calculator();
		c.setOperand(20, 0);

		try {
			c.divide();
		} catch (DivideException e) {
			e.printStackTrace();
			System.out.println("에러 코드: " + e.getErrCode());
		}

	}

}

Calculator Quiz

1. 정수 2개를 입력받는다.
2. 입력된 값이 정수라면 합계를 반환한다.
3. 예외가 발생할 수 있는 상황이라면 메서드를 강제로 종료하고 예외 메시지를 전달한다.
    (throw를 사용해서 예외 객체를 생성할 때, 생성자의 매개값으로 원하는 메시지를 문자열 형태로 전달하면 된다.)
4. MainClass를 생성해서 객체 생성 후 메서드를 호출한다. 예외가 발생했을 시 e.getMessage()를 호출해서 메시지 내용을 출력
5. Scanner의 close()는 항상 진행
package exception.quiz;

import java.util.Scanner;

public class Calculator {

	public int input() throws Exception {
		Scanner sc = new Scanner(System.in);
		
		try {
			System.out.print("정수1: ");
			int num1 = sc.nextInt();
			
			System.out.print("정수2: ");
			int num2 = sc.nextInt();
			
			return num1 + num2;			
		} catch (Exception e) {
			throw new Exception("정수를 입력하시기 바랍니다.");
		} finally {
			sc.close();
		}
		
	}
	
}​
package exception.quiz;

public class MainClass {

	public static void main(String[] args) throws Exception {
		
		Calculator c = new Calculator();
		
		try {
			System.out.println("메서드의 실행 결과: " + c.input());
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
	}

}​

Account Quiz

1. 잔액(balance:long)으로 멤버변수를 선언(private 제한자)
2. deposit:입금기능, withDraw:출금기능, getBalance:잔액확인기능(return->long)
3. withDraw에서 잔액이 출금금액보다 작다면 예외를 발생시키는 코드를 작성(MyException)
4. AccountMain이라는 클래스를 작성해서 예외처리가 작동되는지 확인한다.
package exception.quiz;

public class Account {
	
	private long balance;
	
	public Account(int money) throws MyException {
		if (money <= 0) {
			throw new MyException("입금을 해야 계좌를 개설할 수 있습니다.");
			
		}
		this.balance = money;
	}
	
	public void deposit(int money) throws MyException {
		if (money <= 0) {
			throw new MyException("입금액은 0원 이상이어야 합니다.");
		}
		this.balance += money;
	}
	
	public void withDraw(int money) throws Exception {
		if (this.balance < money) {
			throw new MyException("잔액이 부족합니다.\n" + "부족한 금액: " + (money - this.balance) + "원");
		} else {
			this.balance -= money;
			return;
		}
	}
	
	public long getBalance() {
		return this.balance;
		
	}

}​
package exception.quiz;

public class MyException extends Exception {

	public MyException() {
	}
	
	public MyException(String msg) {
		super(msg);
	}

}​
package exception.quiz;

public class AccountMain {

	public static void main(String[] args) throws Exception {
		
		Account acc = null;
		
		try {
			acc = new Account(1000);
			acc.deposit(200);
			acc.withDraw(500);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("계좌 잔액: " + acc.getBalance());
		
	}

}

 

API

  • API란 Application Programming Interface의 약자로 프로그램 개발에 자주 사용되는 클래스 및 인터페이스의 모음을 말한다.
  • 자주 사용하는 String 클래스와 System 클래스도 API에 속한 클래스다.

java.lang 주요 클래스

Object 클래스

  • 자바의 클래스는 명시적으로 extends를 쓰지 않으면 암묵적으로 Object를 상속받도록 구성되어 있다.
  • 자바의 모든 클래스는 Object 클래스의 메서드를 오버라이딩하여 사용할 수 있다.

System 클래스

  • 운영체제의 기능을 이용하게 해주는 클래스다.
  • 프로그램 종료, 키보드 입력, 모니터 출력, 메모리 정리, 현재시간 읽기, 프로퍼티 읽기 등의 기능을 제공한다.
  • 모든 필드와 메서드는 static으로 되어 있다.

String 클래스

  • 문자열 저장 및 문자열 조작메서드를 제공해 주는 클래스다.

package api.lang.obj;

public class Person implements Cloneable {

	private String name;
	private int age;
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
		
	}
	
	@Override
	public String toString() {
		return "이름: " + this.name + "\n나이: " + this.age + "세";
		
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Person) {
			Person p = (Person) obj;
			if (p.age == this.age) {
				return true;
			}
		}
		return false;
	}
	
	@Override
	protected void finalize() throws Throwable {
		// 생성된 객체가 사라지는 시점에서 자동 실행(가비지 컬렉터가 실행 될 때)
		System.out.println(this.name + "이 소멸 되었습니다.");
	}
	
	// 객체 복사 메서드
	// cloneable 인터페이스를 구현해서 사용해야 한다.
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	
	/*
	public void personInfo() {
		System.out.println("이름: " + name);
		System.out.println("나이: " + age + "세");
	}
	 */
	
}
package api.lang.obj;

public class MainClass {

	public static void main(String[] args) {
		
		Person park = new Person("박영희", 30);
		Person hong = new Person("홍길동", 24);

//		park.personInfo();
//		hong.personInfo();

		// 객체 타입의 변수를 출력하거나 값을 얻을 때
		// 뒤에 자동으로 toString()이 붙어서 진행된다.
		System.out.println(park);
		System.out.println(hong);
		System.out.println(park.hashCode());
		
//		System.out.println(park.age == hong.age); (x)
		
		if (hong.equals(park)) {
			System.out.println("나이가 같습니다.");
		} else {
			System.out.println("나이가 다릅니다.");
		}
		
		// finalize는 가비지 컬렉터가 호출되는 순서가
		// 보장되지 않기 때문에  사용을 권장하지 않는다.
		hong = null;
		park = null;
		System.gc(); // 가비지 컬렉터를 호출. (바로 호출이 안될 수가 있다.)
		
		Person kim = new Person("김복제인간", 100);
		
		try {
			Person clonePerson = (Person) kim.clone();
			System.out.println("복사된 객체 정보: " + clonePerson);
			System.out.println("kim의 주소: " + kim.hashCode());
			System.out.println("복제된 객체주소: " + clonePerson.hashCode());
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			
		}

	}

}
package api.lang.system;

public class SystemTime {

	public static void main(String[] args) {

//		long time = System.currentTimeMillis();
//		System.out.println(time);
		
		long start = System.currentTimeMillis();
		
		int total = 0;
		
		for (int i = 1; i <= 100000000; i++) {
			total += i;
		}
		
		long end = System.currentTimeMillis();
		
		System.out.println("실행 소요시간: " + (end - start) * 0.001 + "초");
		
		System.out.println(System.getProperties());
		System.out.println(System.getenv());
		
	}

}
  • System 클래스가 제공하는 currentTimeMillis()는 1970년 1월 1일 자정을 기준으로 현재까지 소요된 시간을 밀리초(1/1000)로 변환한 long타입의 정수를 반환한다.
package api.lang.String;

import java.util.Arrays;

public class StringExample {
	
	public static void main(String[] args) {

		String str = "Hello Java";
		
		// chartAt(인덱스) -> 해당 인덱스의 단일 문자를 리턴
		char c = str.charAt(4);
		System.out.println("4번 인덱스의 문자: " + c);
		
		// substring(인덱스) -> 문자열의 특정 범위의 문자를 추출
		String s2 = str.substring(6); // 6번 인덱스부터 끝까지 추출
		System.out.println(s2);
		
		// 0번부터 5번 미만까지 추출(끝값을 미만으로 처리함)
		System.out.println(str.substring(0, 5));
		
		// length(): 문자열의 총 길이 리턴
		System.out.println("str의 총 문자 개수: " + str.length());
		
		// indexOf(문자열): 특정 단어의 인덱스르 리턴
		// 단어를 검색하면 해당 단어의 첫글자 인덱스를 리턴
		// 찾는 단어가 없다면 -1을 리턴
		int idx = str.indexOf("o");
		System.out.println("o의 인덱스: " + idx);
		
		idx = str.indexOf("Java");
		System.out.println("Java의 인덱스: " + idx);
		
		idx = str.indexOf("안녕");
		System.out.println(idx);
		
		// toLowerCase(), toUpperCase()
		String s3 = "Hello JAVA WOrlD";
		System.out.println(s3.toLowerCase());
		System.out.println(s3.toUpperCase());
		
		// trim(): 문자열의 앞, 뒤 공백을 제거
		String name = "     		  홍길동			   ";
		System.out.println(name.trim() + "님 안녕하세요.");
		
		// replace(old, new)
		// 기존 문자열 내부의 old문자값을 모두 찾아 new 문자열로 일괄 변경
		String java = "자바 언어를 배우고 있습니다. 자바 심볼은 커피로 사용하고 있습니다.";
		System.out.println(java.replace("자바", "Java"));
		System.out.println(java.replace("습니", ""));
		
		// valueOf: 기본 타입을 문자열로 변경 (static)
		System.out.println(3 + 4);
		System.out.println(String.valueOf(3) + String.valueOf(4));
		
		// split: 문자열을 구분자로 구분하여 분할
		// 분할한 문자들을 String 배열에 담아서 리턴
		String phone = "010-1234-5678";
		String[] numbers = phone.split("-");
		System.out.println(Arrays.toString(numbers));
		
		String pet = "멍멍이, 야옹이, 삐약이";
		String[] pets = pet.split(", ");
		System.out.println(Arrays.toString(pets));
		
	}

}

String Quiz01

1. 스캐너를 통해서 id를 입력 받는다.
2. 참고로 아이디는 공백을 포함할 수 있다.
3. 공백을 제거한 아이디가 5글자 미만이라면 다시 입력받는다.
4. 5글자 이상 입력되었다면 "id가 등록되었습니다."라고 출력 후 종료
package api.lang.String;

import java.util.Scanner;

public class StringQuiz01 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		
		while (true) {
			System.out.print("ID를 입력하세요. ");
			String id = sc.nextLine().trim();
			id = id.replace(" ", "");
			
			if (id.length() < 5) {
				System.out.println("아이디는 5글자 이상입니다. 다시 입력하세요.");
			} else {
				System.out.println("ID가 등록되었습니다.");
				break;
			}
		}
		sc.close();

	}

}​

String Quiz02

1. 주민등록번호 13자리를 입력받는다.
2. 주민번호는 -을 포함해서 받을 예정
3. 13자리가 아니라면 다시 입력받는다.
4. 남자인지 여자인지 구분해서 출력해 주면 된다.
package api.lang.String;

import java.util.Scanner;

public class StringQuiz02 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		outer: while (true) {
			System.out.println("주민등록번호 13자리를 입력하세요.");
			System.out.print("> ");
			String ssn = sc.next();
			
			ssn = ssn.replace("-", "");
			
			if (ssn.length() != 13) {
				System.out.println("주민등록번호는 13자리 입니다. 다시 입력하세요.");
			} else {
				switch (ssn.charAt(6)) {
				case '1':
				case '3':
					System.out.println("남성입니다.");
					break outer;
				case '2':
				case '4':
					System.out.println("여성입니다.");
					break outer;
				
				default:
					System.out.println("잘못 입력했습니다.");
				}
			}
			
		}
		
		sc.close();
	}

}​

String Quiz03

사용자로부터 단어를 하나 입력받고 해당 단어가 회문이라면 "회문입니다."를 출력
회문이 아니라면 "회문이 아닙니다."를 출력.

회문: 똑바로 읽으나 거꾸로 읽으나 똑같은 단어나 문장.

일단 공백이 있다면 공백부터 다 없애고, 입력받은 문자를 반으로 나눈 후
왼쪽과 오른쪽이 동일한 지 반복해서 확인 후 결과를 출력.
package api.lang.String;

import java.util.Scanner;

public class StringQuiz03 {

	public static String palindrome(String word) {

		word = word.replace(" ", "");
		
		/*
        방법 1)
		for (int i = 0; i < word.length() / 2; i++) {
			if (word.charAt(i) != word.charAt(word.length() - i - 1)) {
				return "회문이 아닙니다.";
			}
				
		}		
		return "회문입니다.";
		 */
		
		/*
        방법 2)
		String word2 = "";
		for (int i = word.length()-1; i >= 0; i--) {
			word2 += word.charAt(i);
		}
		
		if (word.equals(word2)) {
			return "회문입니다.";
			
		} else {
			return "회문이 아닙니다.";
			
		}
			return "회문입니다.";
			
		} else {
			return "회문이 아닙니다.";
			
		}
		 */
		StringBuilder sb = new StringBuilder(word);
		if (sb.reverse().toString().equals(word)) {
			return "회문입니다.";
			
		} else {
			return "회문이 아닙니다.";
			
		}
		
	}
	
	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		System.out.print("입력: ");
		String word = sc.nextLine();
		
		System.out.println(palindrome(word));
		
		sc.close();

	}

}​

 

String 클래스의 단점

  • String 클래스는 자주 사용되고, 좋은 기능들을 많이 가지고 있지만 메모리를 과소비하는 단점이 있다.
  • String 객체는 처음 초기화된 데이터에 변화를 주어야 하는 상황에서 기존 객체를 활용하지 않고 새로운 객체를 계속해서 생성한다.

StringBuilder (Java 5 버전부터 사용가능)

  • String 클래스의 단점으로 인한 메모리 과부하 및 속도가 느려지는 현상을 개선하기 위해서 StringBuilder가 새롭게 추가되었다.
  • StringBuilder는 기존 객체를 계속 재활용하면서 실제 객체 내부의 값을 변경하게 된다.
package api.lang.stringbuilder;

public class StrBuilderExample {

	public static void main(String[] args) {

		String str = "hello";
		System.out.println("str의 주소값: " + str.hashCode());
		
		str = "hello wolrd";
		System.out.println("str의 주소값: " + str.hashCode());
		
		str = "hello~!";
		System.out.println("str의 주소값: " + str.hashCode());
		
		System.out.println("-------------------------");
		
		StringBuilder sb = new StringBuilder("hello");
		System.out.println(sb);
		System.out.println("sb의 주소값" + sb.hashCode());
		
		// 문자열을 맨 끝에 추가하는 메서드 append(문자열)
		sb.append(" world");
		System.out.println(sb);
		System.out.println("sb의 주소값" + sb.hashCode());
		
		// 문자열을 특정 인덱스에 삽입하는 메서드 insert(인덱스, 삽입할 문자열)
		sb.insert(6, "my ");
		System.out.println(sb);
		System.out.println("sb의 주소값" + sb.hashCode());
		
		// 특정 인덱스 범위의 문자열을 교체하는 메서드 replace(begin, end, 문자열)
		// end는 끝범위 미만으로 인식된다.
		sb.replace(6, 8, "your");
		System.out.println(sb);
		System.out.println("sb의 주소값" + sb.hashCode());
		
		// 문자열 내의 특정 단어를 삭제하는 메서드 delete(begin, end)
		// delete는 replace와 같이 끝범위는 미만으로 인식된다.
		sb.delete(6, 11);
		System.out.println(sb);
		System.out.println("sb의 주소값" + sb.hashCode());
		
		StringBuilder sb2 = new StringBuilder(str);
		System.out.println(sb2);
		
		String str2 = sb2.toString();
		System.out.println(str2);
		
	}

}

'Programming Language > Java' 카테고리의 다른 글

[국비] Java 내용정리 Day17  (0) 2021.11.29
[국비] Java 내용정리 Day16  (0) 2021.11.28
[국비] Java 내용정리 Day14  (0) 2021.11.24
[국비] Java 내용정리 Day13  (0) 2021.11.23
[국비] Java 내용정리 Day12  (0) 2021.11.21

댓글