[JAVA.12] 유용한 클래스(Useful Class)와 예외처리(Exception Handling) +어노테이션👀

Kama_Code·2023년 7월 22일
1

JAVA

목록 보기
17/20
post-thumbnail
post-custom-banner
  • 이전에 기초 클래스에서 배웠다.
    이번 파트는 디테일이 들어가게 된다.
    프로그램의 생각치 못한 오류가 났을때 처리 방법과
    클래스의 다양한 사용에 대해 다뤄볼 것이다.

<Step.1> 유용한 클래스(Useful Class)

  1. java.lang 클래스
    ㄴimport 하지 않아도 자동으로 Import되는 java 안에 내장되어 있는 라이브러리
    ㄴ많이 사용하는 기본 클래스들이 속한 패키지
  1. Object 클래스
    ㄴ모든 자바 클래스의 최상위 클래스이다
    ㄴ모든 자바 클래스는 Object 클래스로부터 상속을 받는다.
    ㄴ컨트롤 + T를 누르면 족보를 확인할 수 있는데 최상단에 위치함을 볼 수 있다.
  1. toString() 메소드
    ㄴObject 클래스에 정의된 형태: public String toString() { … }
    ㄴ객체 정보를 String으로 바꿔서 사용할 때 많이 사용된다.
    ㄴprintln()메소드로 인자가 전달되면 자동으로 toString() 메소드가 호출된다.
class MyFriends extends Object {
	String myName="성유겸";
	@Override
	public String toString() {
		return "이름:"+ myName;
	}
}
실행결과

public static void main(String[] args) {
	myFriends fnd1 = new myFriends();
	System.out.println(fnd1);
}

★ [이름: 성유겸] 이 출력된다.

  1. equals() 메소드
    ㄴ상속받은 클래스에서 오버라이딩으로 비교하고 싶은 항목을 재정의해서 비교하라는 것.
    ㄴ간단하게 참조값(주소값) 안에 있는 실제 값을 본다.
  • myBook1과 myBook2의 equals 비교는 id만 있기에 id로 비교한다.
    myBook1.author과 myBook2.author의 equals 비교는 값이 있기에 값을 비교한다.
  1. 내부 클래스(Inner class) : 클래스 안에 정의된 클래스로 static이 없는 클래스를 말한다
    • 외부 클래스의 모든 멤버를 사용할 수 있다
    • 정적 멤버를 가질 수 없다. 단 상수는 가질 수 있다
    • 이벤트 기반의 프로그래밍에서 사용된다.
    • 컴파일시 외부클래스 이름 $내부클래스 이름.class 형식으로 파일이 만들어진다
  • 멤버 내부 클래스의 객체는 외부 클래스의 객체에 종속적이다 .
  • 외부 클래스는 내부클래스를 멤버변수처럼 사용할 수 있고,
    내부 클래스는 외부 클래스의 자원을 직접 사용할 수 있는 장점이 있다.

▣ 선언 방법

class OuterClass
{
	...
	class InnerClass
	{
		...
	}
}
  • OuterClass의 객체를 생성한 후 InnerClass의 객체를 생성할 수 있다.
  • InnerClass 내에서는 OuterClass의 멤버에 직접 접근할 수 있다.
  • InnerClass의 객체는 자신이 속할 OuterClass의 객체를 기반으로 생성된다.
  • 정적멤버를 가질 수 없다. 단 상수(final)는 가능하다.

▣ 객체생성 방법

public static void main(String[] args) {
	
	OuterClass outerClass = new OuterClass();
	#내부클래스 생성방법1
	OuterClass.InnerClass in1 = outerClass.new InnerClass();
	#내부클래스 생성방법2
	OuterClass.InnerClass in2 = new OuterClass().new InnerClass();
}
  1. 익명 클래스(Anonymous class) - 이름이 없는 클래스
  • 내부클래스처럼 이벤트 기반의 프로그래밍에서 많이 사용
  • 부모클래스의 메소드를 오버라이딩 하는 것이 목적이다
  • ★★ 마지막에 세미콜론을 반드시 기술해야 한다.
  • 형식: 부모클래스명 참조변수 = new 부모클래스명() {
    익명 클래스의 실행부;
    부모클래스의 메소드 오버라이딩();

▣ 선언 방법

class Person {
	String name;
	public Person(String n) {
		name = n;
	}
	void printInfo() {
		System.out.printf("이름:%s", name);
	}
}
public class AnonymousClass {
	public static void main(String[] args) {		
		Person anonyPerson = new Person("이사람"){
			@Override
			void printInfo() {
				System.out.println("익명클래스에서 오버라이딩");
			}
		};
		anonyPerson.printInfo();
	}
}
  • 이름이 없는 클래스이므로 익명클래스라고 한다.
  • 부모클래스의 메소드를 오버라이딩 하는것이 주된 목적이다.
  • 익명클래스에서 확장한 멤버는 익명클래스 내에서만 접근가능하다.
  • 익명 내부 클래스는 예전에 자바 UI에서 이벤트를 처리하는 데 많이 사용했다.
  • 현재는 안드로이드 프로그래밍에서 위젯의 이벤트 처리하는 핸들러를 구현할 때 사용한다.
  1. Wrapper 클래스
    • 기본자료형의 데이터를 객체화할 때 사용하는 클래스
    • 제네릭 클래스에서는 Box<T, S> 형태의 타입매개변수를 사용하게 되는데
      이때 반드시 Wrapper클래스가 필요하다
  • Wrapper 클래스는 보통 이렇게 사용한다.
public static void main(String[] args) {
	// 정수 34를 객체화 해서 showDate라는 메소드의 인자로 전달한다. 
    Integer integer = new Integer(34); 
	showData(integer);
	showData(new Integer(99));
}
  • parseInt()
    : 숫자형식의 문자열을 숫자로 변경한다.

intValue -> 정수형으로 씌운다. (변환)
doubleValue -> 실수형으로 씌운다. (변환)

  • codePointAt()
    : 문자열에서 index에 해당하는 한 문자의 아스키코드값을 반환한다.

  • isDigit()
    : 문자열이 숫자인지 판단한다.

  • isLetter()
    : 문자 여부를 판단하는 메소드로 특수기호나 숫자형은 false를 반환

  • isWhietspace()
    : 공백문자인지 판단

  • isLowerCase(), isUpperCase()
    : 대소문자를 판단. 단 영문자에만 적용되며 알파벳이 아닌 문자에 적용시 false를 반환

※ 왜 이것을 쓸까?

public static void myFunc(Object obj) {	
	System.out.println(obj);
}
  • myFunc() 메소드는 호출시 기본자료형 데이터 전달이 불가능하다.
  • 이러한 상황에 Wrapper 클래스를 사용하여 아래처럼 데이터를 객체화(인스턴스화) 한다.

▼ int정수형 자료를 가지고 Wrapper 클래스 정의한 예시 ▼

class IntWrapper
{
	private int num;
	public IntWrapper(int data)
	{
		num=data;
	}
	public String toString()
	{
		return ""+num;
	}
}
  1. Number 클래스

    java.lang.Number 클래스는 모든 래퍼 클래스가 상속하는 추상 클래스이다 .

  1. 박싱(Boxing)과 언박싱(Boxing)

    박싱은 인스턴스의 생성을 통해서 이뤄지지만
    언박싱은 래퍼 클래스에 정의된 메서드의 호출을 통해 이뤄진다.

예시 :

  • Boxing : 기본자료형의 데이터를 Wrapper객체로 감싸는것
  • Unboxing : Wrapper객체에서 기본자료 형의 데이터를 꺼내는것
// 10이라는 정수를 suja라는 상자에 박싱(포장했다!)
Integer suja = new Integer(10);	// 박싱
// suja라는 박스 안에 정수형 값을 꺼내어 정수형 unboxing 변수에 꺼냈다!
int unboxing = suja.intValue(); // 언박싱
System.out.println(unboxing);
  1. 오토박싱(Auto Boxing)과 오토언박싱(AutoBoxingUnboxing)
  • Auto Boxing - 기본자료형의 데이터를 자동 으로 Wrapper객체로 감싸는 것을 뜻함

  • Auto Unboxing - Wrapper객체에서 기본자료 형의 데이터가 자동으로 꺼내 지는것을 뜻함

Integer integer = 10;	
System.out.println(integer);

// 객체생성을 하지 않아도 박싱이 된다.
Character ch = 'X'; // Character ch = new Character('X'); : 오토박싱
// 언박싱하지 않아도 값을 꺼낼 수 있다.
char c = ch;        // char c = ch.charValue();           : 오토언박싱
  • 인스턴스가 와야하는데 기본자료형 데이터가 있다면 자동으로 Boxing된다.
  • 데이터를 꺼낼때도 별도의 처리없이 자동으로 Unboxing된다.
  • Auto Boxing, Unboxing은 JDK1.5 이상 부터 지원된다.
  1. Math 클래스
    • Math클래스는 수학 관련 연산 기능을 제공한다.
  • Math클래스에 정의된 메서드는 모두 static으로 선언되어 있다.
  • 즉 Math는 기능의 제공이 목적일 뿐, 인스턴스의 생성을 목적으로 정의된 클래스는
    아니다.
  1. Random 클래스
  • 씨드(Seed)를 기반으로 난수생성
  • 정수형, 실수형, boolean 등 모든 형태의 난수 생성가능
  1. ▣ BigInteger & BigDecimal 클래스
  1. Arrays 클래스
  • 배열의 비교는 두 배열에 저장된 데이터 수, 순서, 그리고 내용 모두가 같을 때
    true를 반환한다.

※ 오름차순 정렬? ( 밑에서부터 산을 올라간다.)
ㄴ값이 작은 순에서 큰 순으로 세워 나가는 정렬
ex) 1, 2, 3, 4, 5, 6, 7

※ compareTo 메소드

interface Comparable
→ int compareTo(Object o)

인자로 전달된 o가 작다면 양의 정수 반환  
인자로 전달된 o가 크다면 음의 정수 반환  
인자로 전달된 o와 같다면 0을 반환
  1. Calendar 클래스
  • java.util.Calendar 클래스
  • 날짜와 시간에 관한 데이터를 손쉽게 처리할 수 있도록 제공하는 추상 클래스
  • add() 메소드
    전달된 Calendar 필드에서 일정 시간 만큼을 더하거나 빼줍니다.
    즉, 특정 시간을 기준으로 일정 시간 전후의 날짜와 시간을 알 수 있습니다.
Calendar time = Calendar.getInstance();
System.out.println(time.getTime());

time.add(Calendar.SECOND, 120);
System.out.println(time.getTime());
  • before()와 after() 메소드
    두 시간상의 전후 관계만을 알고 싶을 경우에는 before()와 after() 메소드를 사용
Calendar time1 = Calendar.getInstance();
Calendar time2 = Calendar.getInstance();
Calendar time3 = Calendar.getInstance();

time2.set(1982, 2, 19);
time3.set(2020, 2, 19);

System.out.println(time1.before(time2));
System.out.println(time1.before(time3));
  • get() 메소드
    전달된 Calendar 필드에 저장된 값을 반환합니다.
Calendar time = Calendar.getInstance();

System.out.println(time.getTime());
System.out.println(time.get(Calendar.DAY_OF_WEEK));
System.out.println(time.get(Calendar.MONTH) + 1);
System.out.println(time.get(Calendar.DAY_OF_MONTH));
System.out.println(time.get(Calendar.HOUR_OF_DAY));
System.out.println(time.get(Calendar.MINUTE));
System.out.println(time.get(Calendar.SECOND));
System.out.println(time.get(Calendar.YEAR));
  • roll() 메소드
    전달된 Calendar 필드에서 일정 시간 만큼을 더하거나 빼줍니다.
Calendar time1 = Calendar.getInstance();
Calendar time2 = Calendar.getInstance();
System.out.println(time1.getTime());


time1.add(Calendar.SECOND, 60);
System.out.println(time1.getTime());


time2.roll(Calendar.SECOND, 60);
System.out.println(time2.getTime());
  • set() 메소드
    전달된 Calendar 필드를 특정 값으로 설정합니다.
Calendar time = Calendar.getInstance();
System.out.println(time.getTime());

time.set(Calendar.YEAR, 2020);
System.out.println(time.getTime());

time.set(1982, 1, 19); // 1은 2월을 나타냄.
System.out.println(time.getTime());

time.set(1982, 1, 19, 12, 34, 56);
System.out.println(time.getTime());

<Step.2> 열거형, 가변 인자, 어노테이션

  • 열거형이란?
    ㄴ관련된 상수(final)들을 같이 묶어 놓은 것.

※ Enum 클래스 : enum 열거체이름 { 상수1이름, 상수2이름, ... }

  1. 열거체를 비교할 때 실제 값뿐만 아니라 타입까지도 체크합니다.
  2. 열거체의 상숫값이 재정의되더라도 다시 컴파일할 필요가 없습니다.
  • 가변 인자란?
    ㄴ기존에는 메서드의 매개변수 개수가 고정적이었나 JDK1.5부터 동적으로
    지정해 줄 수 있게 되었으며, 이 기능을 가변 인자라고 한다.
    ㄴ가변인자를 나타내는 기호(...)를 사용한다.
    ㄴ변수 타입뒤에 붙여주고 변수명을 쓰면 끝
public PrintStream printf(String format, Object... args) { ... }

-> 가변인자는 매개변수 중에서 제일 마지막에 선언해야 한다.

  • 어노테이션(Annotation)이란?
  1. 사전적 의미로는 주석이라는 뜻이다.
  2. 자바에서 Annotation은 코드 사이에 주석처럼 쓰이며 특별한 의미, 기능을 수행하도록 하는 기술이다.

@Override
- 선언한 메서드가 오버라이딩 되었다는 것을 나타냄
- 만약 상위(부모) 클래스( 또는 인터페이스)에서 해당 메서드를 찾을 수 없다면
컴파일 에러를 발생시킵니다.

@Deprecated
- 해당 메서드가 더이상 사용되지 않음을 표시
- 만약 사용할 경우 컴파일 경고를 발생시킵니다.

@SuppressWarnings
- 선언한 곳의 컴파일 경고를 무시하도록 합니다.

<Step.3> 예외처리(Exception Handling)

  • 프로그램을 만들다보면 사람이 만들다보니 완벽할 수만은 없어서 에러가 날 수 있다
    프로그램을 실행했을때 에라가 발생하면 프로그램이 멈추게 되는데
    멈추지 않고 에러를 던져서 프로그램을 계속 이어나가게 하는 매우매우 중요한 내용이다!
  • 예외란?
    예측 가능한 런타임 에러를 예외exception라고 부른다.
    그리고 개발자가 다음과 같은 목적을 위해 제어하고 처리를 한다.

※ 에러의 종류
1. 컴파일 에러(문법 에러)

  • 문법을 잘못 작성하여 발생하며 실행시 오류를 일으키게 됩니다.
  • 어느 곳에 문제가 있는지 컴파일러가 정확한 위치를 알려줍니다.
  • 오류가 발생한 부분을 표시해주기에 수정하고 다시 실행하면 비교적 쉽게 해결할 수 있습니다.

해결방법: try~catch문으로 감싸서 해결이 가능합니다.

  1. 런타임 에러
  • 프로그램 실행중 발생하는 에러

해결방법: 프로그래머의 논리력으로 추적해서 문제가 있는 부분을 찾아야 합니다.

◆ 논리 Error

  • 프로그래머의 논리적 오류에 의해 발생
  • 나눗셈을 할 때 0으로 나눈 경우 발생

◆ 시스템 Error

  • 시스템 자체의 문제에 의해 발생되며 프로그래머가 처리하기 어려운 에러
  • 운영체제, 시스템, 네트워크, 데이터베이스를 확인 후 해결해야 합니다.

◆ Syntax Error

  • 실행 자체가 되지 않는 문법상 오류가 있는 코드
    ㄴ컴파일에러와 비슷합니다.

◆ Semantic Error

  • 프로그램이 오류를 내지 않고 실행되지만 올바르게 동작하지 않은 상태

◆ 로지컬 Error

  • 프로그램이 오류를 내지 않고 실행되지만 프로그래머가 설계한 방향이 아닌
    다른 방향으로 실행이 되는 에러

실행 예외 :

InputMismatchException : 정수형의 자료를 입력받을때 문자를 입력하면 발생

ArrayIndexOutOfBoundsException : 배열의 크기를 벗어난 인덱스를 사용할 경우 발생

ClassCastException : 객체의 형변환이 불가능한 경우 발생

일반 예외 :

  • ▣ try ~ catch 문
    try는 예외가 발생할 가능성이 있는 지역을 감싸는 목적
    catch는 발생한 예외를 처리하기 위한 목적
  • ▣ e.getMessage()
    예외가 발생한 원인을 문자열로 반환한다
    모든 예외 클래스는 Throwable 클래스를 상속하므로 getMessage()메소드를 사용할 수 있다.
  • ▣ 예외처리 방법

메소드에 예외선언: throws를 클래스 뒤에 써서 어떤 예외를 처리하면 되는지
쉽게 알 수 있다.

  • ▣ 여러개의 catch 블럭 정의 (디테일 catch)
    하나의 try블럭에 둘 이상의 catch블럭을 구성할 수 있다.
    컴파일러는 catch블럭을 순차적으로 실행하면서 해당하는 예외가 있는지 검사한다.
    단, Exception클래스나 Throwable클래스는 가장 마지막에 기술해야 한다.

  • Exception
    모든 예외 한 번에 처리하기
    어떤 예외가 발생할지 모를 때 모든 예외의 최상위 클래스를 이용해서
    예외를 처리해줄 수 있다.
    ㄴ단점은 사용자에게 어떤 오류가 발생했는지 디테일한 오류 설명이 불가능하다.

  • 항상 실행되는 finally 블럭
  • ▣ 개발자정의 예외 클래스
    ㄴ개발자가 논리적으로 직접 예외를 처리해야 하는 것도 있다.

<Step.4> 발전을 위한 문제풀이 (kama_code 출제)

업다운 게임을 만들고 예외처리를 추가하여 잘못된 입력에도
프로그램이 종료되지 않도록 구현하시오.
a.입력시 숫자가 아닌 문자를 입력하는 경우
b.1~100 사이의 숫자가 아닌 경우

★ 정답 및 해설 ☆

import java.util.Scanner;

class UpDownGame 
{
	private static int COUNT = 7;
	private int[] arrInput;// 사용자 입력
	private int answer;
	
	public UpDownGame() 
	{
		arrInput = new int[COUNT];
		answer = (int) (Math.random() * 100 + 1);
	}
	public void run() 
	{
		boolean forEnd = false;
		try 
		{
			for (int i = 0; i < arrInput.length; i++) 
			{
				Scanner sc = new Scanner(System.in);
				
				System.out.print("숫자를 입력해주세요 : ");
				int num = sc.nextInt();

				if (num > answer) 
	            {
	                System.out.println("Down ===> " + (COUNT - i - 1) + "번 남아 있습니다.");
	            } 
				else if (num < answer) 
				{
	                System.out.println("Up ====> " + (COUNT - i - 1) + "번 남아 있습니다.");
	            } 
				else 
	            {
	                System.out.println("일치====> " + (i+1) + "번만에 정답!!");
	                
					//사용자가 숫자를 맞추었을 때만 true로 변경한다
	                forEnd = true;
	                
	                break;
	            }
			}
			// false를 유지하고 있다면 맞추지 못한 경우이므로 실패처리
			if (forEnd == false)
			{
				System.out.println("당신은 실패하셨습니다. 노력하세요!");
				return;
			}
		} 
	    catch (Exception e) 
	    {
	        System.out.println("잘못된 입력입니다. 처음부터 다시 입력하세요");
	        return;
	    }
	}
}
	public class QuUpDownException 
	{
		public static void main(String[] args) 
		{
			Scanner sc;
			UpDownGame game;
	
	    while (true) 
	    {
	        try 
	        {
	            sc = new Scanner(System.in);
	            System.out.println("게임시작 1");
	            System.out.println("게임종료 2");
	            System.out.println(">>");
	            
	            int num = sc.nextInt();
	            if (num == 1) 
	            {
	                game = new UpDownGame();
	                game.run();
	            } 
	            else if (num == 2) 
	            {
	            	System.out.println("게임을 종료합니다.");
	            	break;
	            }
	            else
	            {
		            System.out.println("잘못된 입력입니다.");
		            System.out.println("게임을 다시 시작 합니다.");
	                continue;
	            }
	        } 
	        catch (Exception e) 
	        {
	            System.out.println("잘못된 입력입니다.");
	            System.out.println("게임을 다시 시작 합니다.");
	        }
	    }
	}
}

여기까지 자바(java) 공부의 중반부까지 끝났다.
다음 파트부터는 자바(java) 공부의 후반부로 들어간다.
앞으로 코드는 점점 짧아진다.
점점 코드는 발전하고 좀 더 쉽게 좀 더 효율적으로 좀 더 편리함을 계속
추구하여 발전하기 때문이다.

profile
[Java SQL HTML CSS JS Studying] 발전을 꿈꾸며 이상을 실현합니다
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 7월 22일

개발자로서 성장하는 데 큰 도움이 된 글이었습니다. 감사합니다.

1개의 답글