본문 바로가기

코딩공부일지/수업 review

자바: abstract & interface & 예외

Part1. 추상클래스, 추상메서드


1. 추상메서드란?
- 메서드의 선언부만 있고 구현부는 없는 미완성 메서드( method body가 존재하지 않는 미완성 메서드)
- 예약어 abstract를 사용하여 정의 (붙이지않을 시 컴파일 에러)
(This method requires a body instead of a semicolon)

 [추상메서드 표현법]
 접근제한자 abstract 반환형 메소드명();
 public abstract void rule () ;

2. 추상클래스란?
- 추상메서드를 포함하고 있는 클래스
- 미완성 메서드가 하나라도 포함되는 순간 해당 클래스는 미완성클래스(추상클래스)가 됨
=> 해당 클래스도 예약어로 abstract를 붙여야 함(미포함시 컴파일에러 발생)
(The type ~~ must be an abstract class to define abstract methods)

 [추상클래스 표현법]
 접근제한자 abstract class 클래스명 { }
 Public abstract class Study {
 ...
 	public abstract void method1();  --> 추상 메서드를 포함하고 있음
 
 }


3. 추상클래스 타입 참조변수와 다형성
- 추상클래스로는 객체생성이 불가함

 AbstractClass ac = new AbstractClass()
 
 추상클래스 타입으로 객체를 생성하려 하면 , 컴파일 에러발생 
 --> Sport cannot be resolved to a type
  -  Cannot instantiate the type AbstractClass

- 추상클래스 타입의 참조변수 선언은 가능
=> 부모타입 변수 선언이 가능하면, 다형성 적용이 가능함
==> 다형성을 이용하여 자식객체를 받아주는 용도로 사용
===> 자식클래스를 생성하여,
부모클래스의 미구현 메소드를 구현한 후 (자손클래스는 미완성 클래스가 아님)
자식클래스 타입의 객체를 생성한 후, 부모타입(추상클래스) 참조변수에 대입
( 자식타입 객체 -> 부모타입 참조변수 대입, upcasting)

		AbstractClass ac;                            --> 추상클래스 타입의 참조변수 ac 선언
        AbstractClass ac = new AbstractChild();   --> 변수 ac에 추상클래스를 구현한 자손 객체 대입


4. 추상클래스의 활용
- 추상클래스 == 일반필드 + 일반메서드 + 추상메서드 (생략가능)
===> 추상메서드가 없어도 추상클래스로 정의 가능
- 추상클래스를 이어받는 자손객체에서 추상클래스의 미완성 부분을 완성

public abstract Class Test {



}
 ===> 추상메서드를 포함하고 있지 않지만, 추상클래스로 정의가 가능하다

- 기술적으로 해당 클래스로는 객체 생성이 불가해야한다고 판단시 추상클래스 생성
- 개념적으로 해당 클래스의 구현이 구체적이지 않을 때 미완성 클래스임을 알려줄 목적으로 정의

public abstract class Sport {       추상메서드 rule을 포함하는 추상클래스 Sport
...
   public void abstract rule();
   .... 
}

public class Soccer extends Sport {    추상클래스 Sport를 상속받은 Soccer 클래스
		public void rule () {     
        오버라이딩을 통해 조상클래스의 미완성 메서드 구현 (더이상 추상메서드, 클래스가 아님)
		System.out.println("음주후 경기참여 불가");       
}

public class Soccer extends BasketBall {    추상클래스 Sport를 상속받은 클래스
		public void rule () {    
        오버라이딩을 통해 조상클래스의 미완성 메서드 구현 (더이상 추상메서드, 클래스가 아님)
		System.out.println("몸싸움 금지!");
}




public static void main(String[] args) {

        Sport s;                      추상클래스 타입 참조변수 선언
		Sport s1 =  new Soccer();     추상클래스 타입 변수에 자손클래스 객체 대입(자동형변환, upcasting) 
                                             < 다형성 적용 : 부모타입 참조변수->자손객체> 
		
		// 객체배열
		Sport[] arr = new Sport[2]; 
		arr[0] = new Soccer();         부모타입 배열의 인덱스에 자손타입 객체대입
		arr[1] = new Baseball();
		
		for (int i=0; i<arr.length; i++) {         soccer의 rule메서드, basketball의 rule 메서드 호출
			arr[i].rule();
		}

 

 

 

 

*** 위 코드에 대해 궁금했던 부분에 대한 gpt답변 추가

 

나는 현재 자바의 추상클래스에 대해서 공부하고 있는데 잘 이해가 가지 않는 부분이 있어.

아래코드에서 Sport 클래스의 rule은 구현부가 없는 추상메소드야.
그런데 arr 객체배열의 각 인덱스의 참조변수 타입은 부모티입은 Sport야. 그럲데 어떻게 메소드 호출이 가능하지? Sport 타입의 rule메소드는 구현부가 없는걸.

public abstract class Sport {       추상메서드 rule을 포함하는 추상클래스 Sport
...
   public void abstract rule();
   .... 
}

public class Soccer extends Sport {    추상클래스 Sport를 상속받은 Soccer 클래스
public void rule () {     
        오버라이딩을 통해 조상클래스의 미완성 메서드 구현 (더이상 추상메서드, 클래스가 아님)
System.out.println("음주후 경기참여 불가");       
}

public class Soccer extends BasketBall {    추상클래스 Sport를 상속받은 클래스
public void rule () {    
        오버라이딩을 통해 조상클래스의 미완성 메서드 구현 (더이상 추상메서드, 클래스가 아님)
System.out.println("몸싸움 금지!");
}




public static void main(String[] args) {

        Sport s;                      추상클래스 타입 참조변수 선언
Sport s1 =  new Soccer();     추상클래스 타입 변수에 자손클래스 객체 대입(자동형변환, upcasting) 
                                             < 다형성 적용 : 부모타입 참조변수->자손객체> 

// 객체배열
Sport[] arr = new Sport[2]; 
arr[0] = new Soccer();         부모타입 배열의 인덱스에 자손타입 객체대입
arr[1] = new Baseball();

for (int i=0; i<arr.length; i++) {         soccer의 rule메서드, basketball의 rule 메서드 호출
arr[i].rule();

ChatGPT
Java의 추상 클래스와 다형성에 대해 질문하셨군요. 이해가 가지 않는 부분을 명확히 하기 위해 Java의 추상 클래스와 다형성에 대해 설명하겠습니다.

Java에서 추상 클래스는 하나 이상의 추상 메서드를 포함할 수 있는 클래스입니다. 추상 메서드는 선언만 있고 구현이 없는 메서드이며, 구현은 추상 클래스를 상속받는 하위 클래스에서 이루어집니다. 즉, 추상 클래스는 일종의 '템플릿'이나 '규약'을 제공하는 역할을 하며, 실제 행동은 이를 상속받은 구체적인 클래스에서 정의됩니다.

Sport 추상 클래스는 rule이라는 추상 메서드를 정의하고 있으며, 이는 Sport를 상속받는 모든 하위 클래스가 rule 메서드를 구현해야 함을 의미합니다. 예를 들어, Soccer와 Baseball은 Sport의 rule 메서드를 각각 구현합니다.

다형성은 객체 지향 프로그래밍의 주요 개념 중 하나로, 참조 변수가 여러 형태의 객체를 참조할 수 있도록 합니다. 이 경우, Sport 타입의 참조 변수는 Sport를 상속받는 모든 객체, 예를 들어 Soccer 객체나 Baseball 객체를 참조할 수 있습니다.

main 메서드에서 arr 배열은 Sport 타입의 참조 변수로 구성됩니다. 이 배열의 각 요소는 Sport를 상속받는 Soccer와 Baseball 클래스의 인스턴스를 참조할 수 있습니다. for 루프를 사용하여 arr 배열의 각 요소에 대해 rule 메서드를 호출할 때, Java 런타임은 각 요소의 실제 객체 타입에 따른 rule 메서드의 구현을 찾아 호출합니다. 이 과정에서 메서드 오버라이딩이 중요한 역할을 합니다.

메서드 오버라이딩이란 하위 클래스에서 상위 클래스의 메서드를 재정의하는 것을 말합니다. Soccer와 Baseball 클래스에서 rule 메서드를 오버라이딩하면, Sport 타입의 참조 변수가 실제로는 Soccer나 Baseball 객체를 참조하고 있을 때 해당 객체의 rule 메서드 구현이 호출됩니다.

다음은 당신의 코드에서 발생하는 일련의 사건들입니다:

Sport[] arr는 Sport 객체의 배열을 선언합니다. 여기서 Sport는 추상 클래스이므로 인스턴스를 생성할 수 없지만, 참조 타입으로 사용할 수 있습니다.
arr[0]과 arr[1]에는 Soccer와 Baseball 객체가 할당됩니다. 이는 다형성의 한 예로, Sport 타입의 배열에 그것을 상속받는 클래스의 객체를 저장할 수 있습니다.
for 루프는 배열을 순회하면서 각 객체의 rule 메서드를 호출합니다. arr[i].rule() 호출 시, Java는 실제 객체 타입의 rule 메서드 구현을 실행합니다.
Soccer와 Baseball 클래스는 Sport 클래스의 rule 메서드를 구현하므로, 이들 각각의 rule 메서드 구현이 호출됩니다.
이것은 다형성과 상속이 Java에서 어떻게 작동하는지를 보여주는 좋은 예시입니다. 코드에서 Sport 타입의 참조 변수가 실제 Soccer 또는 Baseball 객체를 가리킬 때, 해당 객체의 오버라이딩된 rule 메서드가 호출되어 실행됩니다.




User
잘 알겠어. 추가로 궁금한 점이 있어. 만약에 sport에는 rule() 메소드만 존재하며, Baseball 클래스에는 rule(), regulation() 두개의 메소드가 존재한다고 가정할게. 그러면 아래의 코드는 정상 작동할 수 있을까?

Sport[] arr = new Sport[2]; 
arr[0] = new Baseball();         부모타입 배열의 인덱스에 자손타입 객체대입
arr[1] = new Baseball();

for (int i=0; i<arr.length; i++) {         soccer의 rule메서드, basketball의 rule 메서드 호출
arr[i].regulation();
ChatGPT
아니요, 이 코드는 정상적으로 작동하지 않을 것입니다. 이유는 Sport 클래스에는 regulation() 메소드가 정의되어 있지 않기 때문입니다. Sport[] arr는 Sport 타입의 참조 변수들로 구성된 배열이며, Sport 타입의 참조 변수로는 Sport 클래스에 정의된 메소드만 호출할 수 있습니다.

Java에서는 참조 변수의 타입이 실제로 호출할 수 있는 메소드를 결정합니다. Sport 타입의 참조 변수를 사용하면, Sport 클래스에 정의되어 있는 메소드만 호출할 수 있습니다. Baseball 클래스에 추가적으로 정의된 regulation() 메소드는 Sport 타입의 참조를 통해서는 접근할 수 없습니다.

만약 Baseball 객체를 Sport 타입의 배열에 할당했다면, 이 배열을 통해 Baseball 객체의 rule() 메소드는 호출할 수 있지만, regulation() 메소드는 호출할 수 없습니다. 이 메소드를 호출하기 위해서는 Baseball 타입으로 다운캐스팅을 해야 합니다. 다운캐스팅은 명시적으로 수행해야 하며, 객체의 실제 타입이 다운캐스팅하려는 타입과 일치할 때만 안전하게 수행할 수 있습니다.

예를 들면 다음과 같이 할 수 있습니다:

java
Copy code
for (int i=0; i<arr.length; i++) {
    if (arr[i] instanceof Baseball) { // arr[i]가 Baseball의 인스턴스인지 확인
        Baseball baseball = (Baseball) arr[i]; // 다운캐스팅
        baseball.regulation(); // 이제 regulation 메소드 호출이 가능
    }
}
위의 코드는 instanceof 연산자를 사용하여 배열의 각 요소가 Baseball 타입인지 확인하고, 다운캐스팅 후 Baseball 클래스의 regulation() 메소드를 안전하게 호출합니다.




User
궁금한 것이 있어. 그럼 위 코드에서 rule()메소드를 호출할 때 Sport, Baseball 각각 rule메소드를 가지고 있잖아. 그럼 부모타입의 메소드를 호출할지 자손타입의 메소드를 호출할지는 어떻게 결정해?? 자식타입에서 오버라이딩된 메소드가 있다면, 무조건 자손타입 메소드가 호출되는거야?
ChatGPT
Java에서는 객체의 실제 타입에 있는 메서드가 호출됩니다, 즉 다형성의 개념에 따라서 메서드 호출은 컴파일 타임(소스 코드가 컴파일되는 시간)에 결정되는 것이 아니라 런타임(프로그램이 실행되는 시간)에 결정됩니다. 이를 "동적 메서드 디스패치" 또는 "런타임 다형성"이라고 합니다.

Sport 타입의 변수가 실제로 Baseball 객체를 참조하고 있을 때, Sport 클래스에서 선언된 rule() 메서드를 호출하면 Java 런타임은 Baseball 객체의 rule() 메서드를 찾아 실행합니다. 이는 Baseball 클래스가 Sport 클래스의 rule() 메서드를 오버라이딩(재정의)했기 때문입니다.

자손 타입에서 오버라이딩된 메서드가 존재한다면, 그 메서드는 부모 타입의 메서드를 "가립니다". 따라서 부모 타입 참조 변수가 자손 타입 객체를 가리킬 때 해당 객체의 오버라이딩된 메서드가 호출됩니다. 이는 객체 지향 프로그래밍의 핵심 원칙 중 하나로, 프로그램이 더 유연하고 확장 가능하도록 돕습니다.

정리하자면, Sport 타입의 참조 변수로 Baseball 객체의 rule() 메서드를 호출하면, Baseball 클래스에 정의된 오버라이딩된 rule() 메서드가 실행됩니다. 이것은 Java가 메서드를 호출할 때 참조변수가 아니라 객체의 실제 타입을 기준으로 메서드를 결정하기 때문입니다.

 

 

 

 

 


Part2 인터페이스

1. 인터페이스란?
- 상수필드와 추상메서드만으로 이루어진 , 추상 클래스의 변형체
- 추상메서드의 집합 (껍데기) , 구현되어 있는 것이 없 음!
- 인터페이스 필드는 "무조건" 상수필드
- 인터페이스의 메소드는 "무조건" 추상메소드

[표현법]
 접근제한자 interface 인터페이스명 {
    상수필드 ; (접근제한자, 예약어 생략가능 --> 암묵적으로 public static final임)
    추상메서드;  (접근제한자, 예약어 생략가능 --> 암묵적으로 public abstract 임) 
    
 }
public interface Basic {

	int num  = 10; 
	void sleep();

2. 인터페이스를 상속받는 클래스

  [표현법]
  A (자식클래스) extends B(부모클래스) implements C(인터페이스)
public class Cat extends BigAnimal implements Animal {

}

3. 추상클래스와 인터페이스 비교

  공통점 차이점
추상클래스 해당 클래스로 객체 생성 불가능,
참조변수로 사용 가능 (다형성 적용가능)


상속받는 클래스에서 추상메소드를 오버라이딩하도록 강제함
(자손클래스가 추상메소드를 제대로 구현하지 않을 시 해당 클래스는 추상클래스로 남음)
추상클래스는 "추상메소드를 포함하는 클래스"임
==> 추상클래스는 클래스 멤버로 일반필드, 생성자, 일반메소드 포함이 가능함

추상클래스는 추상클래스를 상속받아서 필드, 메소드를 이용하고 클래스를 확장하기 위한 용도

다중상속 불가
인터페이스 인테터페이스는 추상 메서드, 상수필드로만 구성된 클래스
(껍데기만 있음)
==> 일반필드, 일반메소드 생성이 불가함
인터페이스는 클레스의 기능 구현(메소드)을 강제하기 위해 사용

다중상속 허용
==> 메소드가 겹치더라도 최종 구현은 실제 구현클래스에서
==> 무조건 구현해야 하는 메서드가 있을 때에는 인터페이스 틀을 만들어 상속하도록 함 ( 오버라이딩 )
==> 추상클래스보다 강한 규칙성과 강제성



public interface Basic {

	int num  = 10; // static 이텔릭체, final 볼드 ===> 인터페이스에 들어오는 모든 필드는 상수필드이므로 추가로 static final을 붙이지 않아도됨
	
    /* public abstract */void sleep();  ==> 반환형은 적어야함!
                                            반환형+메소드명(선언부);
    }
public abstract class Person {				// 추상클래스
	1. 필드부
	private String name;
	private double weight;
	private int health;
	
    2.생성자부
	public Person() {                                             기본생성자
		super();
	}

	public Person(String name, double weight, int health) {      조상의 생성자
		super();
		this.name = name;
		this.weight = weight;
		this.health = health;
	}
	3. getter-setter생략, toString오버라이딩

	
	@Override
	public String toString() {
		return "Person [name=" + name + ", weight=" + weight + ", health=" + health + "]";
	}
    
 	4. 메서드부: 추상메서드
	public abstract void eat();
	public abstract void sleep();
}
public class 클래스명 extends 상속받는 추상클래스 implements 상속받는 인터페이스
public class Mother extends Person implements Basic {
	1. 필드부
	private int babyCount;
    2. 생성자부
	public Mother() {
		super();
	}

	public Mother(String name, double weight, int health, int babyCount) {
		super(name, weight, health);
		this.babyCount = babyCount;
	}
    3. getter-setter생략, toString오버라이딩
	@Override
	public String toString() {
		return super.toString() +"Mother [babyCount=" + babyCount + "]";		
	}
	4. 메서드부
	public void eat() {
		super.setWeight(super.getWeight()+10);
		super.setHealth(super.getHealth()+15);
	}
		
	public void sleep(){
		super.setHealth(super.getHealth()+15);
		
	}

 

public class Baby extends Person implements Basic{
	1. 필드부 없음
	2. 생성자부    
	public Baby() {		
	}	
	public Baby(String name, double weight, int health) {
		super (name, weight, health);
	}
    3. toString 오버라이딩
	@Override
	public String toString() {
		return "Baby [" + super.toString()+"]";
	}
    4. 메소드 오버라이딩 (추상메서드 구현)
  	@Override 
  	public void eat() { // 아기가 밥을 먹는다
	  => 몸무게 5증가 
	  => weight ==> 부모의 필드 +5 ==> 필드에 값을 수정하는,, set작업임
	  => 자기자신의 필드가 아니라, 부모에게 물려받은 필드에 접근해야 하므로
      => super. 을 통해 조상의 getter와 setter에 접근하여 
        getter로 변동시킨 값을 setter을 이용해 대입
	 super.setWeight(super.getWeight()+5);  
	 super.setHealth(super.getHealth()+5);
  }
  
 	@Override
 	public void sleep () {
		 super.setHealth(super.getHealth()+10);
 	}
  
}
public class Run {
	public static void main(String[] args) {
		//Person p = new Person();
		==> person은 추상클래스이므로 객체생성이 불가함 
		
  	 	Person b = new Baby("아기", 5.3 , 90);
		Person mom = new Mother("엄마",50,90,1);
		
		System.out.println(mom);  // 호출시, mom클레스가 참조하고 있는 객체의 실체는 Mother형이기 때문에	
								// Mother(자식)클래스에 있는 toString이 우선권을 가짐
								// 따라서, 자손타입인 Mother의 toString이 출력됨
		System.out.println(b);
		
		mom.eat(); // 엄마 몸무게, 건강도 +
		b.eat();
		mom.sleep(); // 엄마 건강도++
		b.sleep();
		
		
		System.out.println("===다음날 ===");
		System.out.println(mom);
		System.out.println(b);
		
		//2. 인터페이스 적용 후 (Person 을 baby로 바꾼다)
		System.out.println("==인터페이스 적용 후 ==");
		
		Basic b1 = new Baby("아기", 5.3 , 90);
		Basic mom1 = new Mother("엄마",50,90,1);
		
		System.out.println(mom1);  // 호출시, mom클레스가 참조하고 있는 객체의 실체는 Mother형이기 때문에	
								// Mother(자식)클래스에 있는 toString이 우선권을 가짐
								// 따라서, 자손타입인 Mother의 toString이 출력됨
		System.out.println(b1);
		
		mom.eat(); // 엄마 몸무게, 건강도 +
		b.eat();
		mom.sleep(); // 엄마 건강도++
		b.sleep();
		
		
		System.out.println("===다음날 ===");
		System.out.println(mom);
		System.out.println(b);
		
	}

}



Part2 예외
1. 프로그램 에러와 예외

1) 프로그램 에러:
프로그램 실행 중 어떠한 원인에 의하여 프로그램이 오작동하거나 비정상 종료되는 경우,
이러한 결과를 초래하는 원인을 "프로그램 에러" 또는 "오류"라 칭함
2) 예외: 에러 중, 시스템에러를 제외한 컴파일, 런타임, 논리에러 등 비교적 덜 심각한 에러
발생시점에 따라 "컴파일 에러" / "런타임 에러" / "논리적 에러"로 구분

2. 에러, 예외의 종류

1) 에러 (error): 프로그램 코드에 의해 수습불가한 심각한 오류
시스템에러 (컴퓨터가 망가지거나,,전원이 나가거나,,)
: 컴퓨터의 오작동으로 발생하는 에러 ==> 소스코드 수정으로 해결불가
virtual machine error, assertation error,,,,etc

2) 예외 (exception) :프로그램 코드에 의해 수습될 수 있는 미약한 오류
1 > 컴파일 에러
: <프로그램 실행 전> 소스코드상의 문법적인 문제로 발생하는 에러
==> 소스코드 수정으로 해결이 가능함
2> 런타임에러
: < 프로그램 실행 중> 발생하는 에러
==> 소스코드 상 문법적 문제는 없으나, 컴파일 이후 발생하는 에러
==> 개발자가 예측 가능한 경우 처리를 안했을 때
==> 사용자 의 잘못일 가능성도 있음
(알파테스트, 베타테스트)
3> 논리적 에러
: 소스코드상 문제도 없고, 실행도 가능하지만
설계 의도와 다르게 프로그램이 동작하는 것 (기획과 설계가 잘못되었을 경우)
checked error, unchecked error 로 나눔


3. 예외관련 상속계층도
Object= > Throwable => Exception => Checked / Unchecked (Runtime)
Error IO,EOFE,FileNotFound..

https://www.benchresources.net/exception-hierarchy-in-java/
https://www.geeksforgeeks.org/exceptions-in-java/


4. Checked /Unchecked 에러

1) checked exception(Exception 클래스와 그 자손):
예외처리 필수 (try-catch) /
IO excption, ClassNotFoundException, 등
2) unchecked exception(RuntimeException과 그 자손, Null Pointer Exception과 그 자손):
비교적 덜 심각한 오류이기 때문에 예외처리 필수아님
ArithmerticException, ClassCastException 등

=> unchecked exception( runtime exception)

RuntimeExcepiton들의 공통점:
개발자가 사전 예측이 가능함 --> 예외처리가 필수가 아니며, 조건문으로도 해결이 가능함

NullPointer Exception: 주소값 객체를 참조했더니 그 값이 null이 들어있을 경우 발생하는 예외
ArrayIndexOutOfBoundsException : 배열의 부적절한 인덱스로 접근했을 때 (없는 인덱스에 접근)
ClassCastException: 허용할 수 없는 형변환을 진행할 경우 발생하는 예외
ArithmeticExcepiton: 나누기연산을 0으로 하면 발생하는 예외
NegativeArraySizeException: 배열크기를 음수로 지정할 경우 발생하는 예외
InputMismatchException
.....etc...


5. 예외처리(Exception handling)
1) 예외처리란?

정의: 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것
목적: 프로그램의 비정상 종료를 막고, 정상적인 실행상태 유지

2) 예외를 막는 방법
1> 조건문 : 예외발생 원천차단

if(num2  != 0 ) {
		System.out.println("나눗셈 결과 :  "+(num1 / num2));		
		} else {
			System.out.println("입력할 수 없는 값입니다");			
		}
		System.out.println("종료합니다");

6. 예외처리 구문 : 예외가 발생했을 때 실행할 내용을 정의해두는 것
- 예외처리 O ,X 의 차이

예외처리 O : 프로그램이 죽지 않고 예외처리 구문 수행 후, 그 다음 코드 수행
예외처리 X: 에러가 난 부분에서 프로그램이 멈춤 (하단 문장은 수행하지 않음)

1) try- catch 문
- 다중 catch문: try블럭 내 처리해야할 예외가 여러개일 때 수행, try-catch-catch-catch
- Exception: 모든 예외클래스는 Exception클래스의 자손이므로,
catch블럭의 ()에 Exception 타입 참조변수 선언 시 모든 종류의 예외 처리 가능
] ==>마지막 catch 문으로 넣을 것
2) printStackTrace()와 getMessage()
- catch문의 실행블럭에 넣음

printStackTrace() : 예외발생 당시 호출스텍에 있었던 메서드 정보와 예외 메세지 화면 출력
getMessage() : 발생한 예외클래스의 인스턴스에 저장된 메세지 출력

3) finally 블럭:

try {                           예외 발생이 가능한 구문 (num1/ num2)		
   [1] try문에서 예외가 발생했을 경우, 발생한 예외와 일치하는 catch블럭이 있는지 확인
       1> 일치하는 catch문이 있을 경우:  
         try블럭을 빠져나가 해당 예외의 catch문의 실행부를 실행 (예외가 해결되는 것은 아님!) 
         try 구문에서 예외가 발생한 라인 하단 부분은 실행하지 않음
       2> 일치하는 catch문이 없을 경우:
          에러 해결 불가
   [2] try문에서 예외가 발생하지 않은 경우
       ===> try문을 모두 수행 후 catch문을 건너뜀 
      
} catch ( 처리하고자하는 예외와 같은 타입의 참조변수1  e) {
		      해당 예외가 발생했을 때 실행할 구문 / e.printStackTrace();
                                               / e.getMessage();
} catch ( 발생예외클래스명2   매개변수명 / e) {
		   해당 예외가 발생했을 때 실행할 구문
} catch ( 발생예외클래스명3   매개변수명 / e) {
		   해당 예외가 발생했을 때 실행할 구문
} finally {
           ***  예외 발생유무와 관계없이 실행할 문장
}

4) throws문 (예외 떠넘기기)
- 현재 메소드를 호출한 곳에 예외를 떠넘겨서(위임하여) 처리, 예외발생한 메소드를 부른 곳에서 예외를 처리해야함
- 메서드 선언부에 키워드 throws사용 -> 메서드 내에 발생가능한 예외를 기입
- 예외가 여러개일 시 쉼표로 구분

 void method() throws Exception1, Exception2, ExceptionN {
 // 메서드 내용
 }


- 예외의 최고조상인 Exception클래스를 메서드에 선언할 시, 해당 메서드는 모든 종류의 예외가 발생 가능함을 의미

void method() throws Exception{
//메서드내용
}

 

'코딩공부일지 > 수업 review' 카테고리의 다른 글

API  (0) 2022.09.27
컬렉션 개념, ArrayList  (0) 2022.09.22
자바: 다형성  (0) 2022.09.20
자바 - 상속 & 오버라이딩  (0) 2022.09.20
자바 - 객체지향프로그래밍2( 오버로딩, 객체배열)  (0) 2022.09.14