본문 바로가기
코딩/수업 정리

20.12.16 Wed [018] 예외처리, 가상머신

by 6^6 2020. 12. 16.
728x90
  • 예외처리 끝
  • 자바의 가상머신 메모리모델

 

 

예외처리 꼭 해야할것

예외처리 관계도

try-catch 평소에도 넣는 연습

recource보단 try-catch-finally로 연습하기

 

 

 

 

18-20 예외 클래스의 구분

 

 

 

 

18-21 Error 클래스를 상속하는 예외 클래스들의 특성

 

 

 

18-22 RuntimeException 클래스를 상속하는 예외 클래스들의 특성

ArithmeticException(연산오류 0나누기) ClassCastException(클래스오류) IndexOutOfBoundsException(배열 넘길때)

   이거 3개는 무조건 외우기

 

 

 

 

 

18-23 Exception 클래스를 상속하는 예외 클래스들의 특성

↑예외의 처리를 어떻게 할 것인지 반드시!!!명시해주기!!!!

 

 

 

 

 

18-24 Exception을 상속하는 예외의 예

18-24 설명. try{ } catch{ }를 지우면 에러뜬다 = 이걸 checked error 라고한다.

try,catch는 없어도되는데 오류가 왜 뜰까?

newBufferedWriter - F3 - throw IOExceptioned을 던지고있음 (IOExceptoned는 checked exception 이다.)

따라서 무조건 try catch를 써야하는 에러이다. newBufferedWriter함수를 쓰기위해서는 checked예외를 던지고있기때문에 무조건 try catch를 써야한다.

write역시 F3누르면 throw IOExceprioned 를 던지고있음

 

1.try-catch로 묶거나

2.throws IOException을 함수뒤에!(public static void 함수이름( )"여기에throws Exception"{ }) 던져줘야함 - 다형성 적용된것임.

이게 무슨말? 만약 public static void md2()함수에서 문제가 생기면 throws IOException은 md2(자기함수)를 호출한 public static void md1()에게 던진다. 그걸 어디서받음? 마지막에 try-catch에있는 catch(IOException)에서 받는다.

 

//18-24 예제
package java_1216;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ExceptionClass {
	public static void main(String[] args) {
		Path file = Paths.get("C:\\javastudy\\Simple.txt");
		BufferedWriter writer = null;

		try {
			writer = Files.newBufferedWriter(file);
			writer.write('A');
			writer.write('Z');

			if (writer != null)
				writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
} // → C:\\javastudy폴더 Simple.txt 확인

↓결과

 

 

//18-24 추가예제 - 교육용이니 메인함수에 실무에선 throw Exception쓰면 XXX

package java_1216;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
										//try-catch없어서 오류남
public class ExceptionClass {
	public static void main(String[] args) throws Exception {//어디다 던져주지? 
    														//얘 실행시킨놈 = JVM 
		Path file = Paths.get("C:\\javastudy\\Simple.txt");
		BufferedWriter writer = null;

			writer = Files.newBufferedWriter(file);
			writer.write('A');
			writer.write('Z');

			if (writer != null)
				writer.close();
	}	
} // → C:\\javastudy폴더 Simple.txt 확인

**throws는 함수단위로 넘기는것. class단위로는 넘기지않는다.

 

 

 

18-25 처리하거나 아니면 넘기거나

 

//18-25예제
package java_1216_;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ioexcepton_class {
	public static void main(String[] args) {
		try {
			md1();
		} catch (IOException e) {
			e.printStackTrace();

		}
	}

	public static void md1() throws IOException {
		md2();
	}

	public static void md2() throws IOException {
		Path file = Paths.get("C:\\javastudy\\Simple.txt");
		BufferedWriter writer = null;
		writer = Files.newBufferedWriter(file);

		writer.write('A');
		writer.write('Z');

		if (writer != null)
			writer.close();
	}
}

 

 

 

 

18-26 둘 이상의 예외 넘김에 대한 선언

 

 

 

18-27 프로그래머가 정의하는 예외 클래스 - 거의 안씀.... 걍 만들수있다는것만 알아두기

 

 

 

 

 

 

18-29 잘못된 catch 구문의 구성 - 상식적으로 접근하기

//18-26 추가 예제
package java_1216_;

import java.util.InputMismatchException;

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

		try {
			int num = 6 / 0;

		} catch (ArithmeticException e) { // 0으로 나눌때 오류
			e.printStackTrace();
			System.out.println("오류");

		} catch (InputMismatchException e) {
			e.printStackTrace();
			System.out.println("오류");
		} catch (Exception e) { //만약 Exception을 제일위에 최고부모로 가게되면
					//에러뜸! why? 다형성(Polymorphism)때문에
                            //오류내용:Unreachable catch block for ArithmeticException. 
                            //부모가 제일 위에있어야한다!!
			e.printStackTrace();
			System.out.println("오류");
		}
	}
}

 

 

 

 

18-30 finally

 

보통 연습으로는 try-catch-finally를 쓰자

 

 

 

18-31 finally 구문의 사용의 예

finally는 error가 있든 없든 무조건 마지막은 finally로 간다.

 

 

 

 

18-32 try-with-resources (16버전이하엔 없다.-하지만 알아야함. 1.신규개발 2.유지보수 )

rescources = 객체. 하나의 메모리

try(여기에 객체 생성해주면)

굳이 close를 쓰지않아고 try-catch문이 알아서 종료해준다.

 

 

 

 

19강

 

 

 

 

 

 

19-2 운영체제 입장에서 자바 가상머신

OS

프로그램   프로그램   프로그램

JVM          JVM         JVM(프로그램 수만큼있다.)

 

 

 

 

 

 

19-3 자바 가상머신의 메모리 모델  각 어떤것들이 들어가는지 알아두기

메소드의 바이트코드 = 메소드의 0101덩어리

 

stack = 함수의 주소가 들어간다.

main함수 부름 -> println 부름

main함수는 콜스택으로 구현 - 스택영역이라고 하는것임

 

메소드 = static 

 

힙 = new 객체 들어감

 

 

 

 

19-5 메소드 영역

static이기때문에 메소드영역으로 올라간다.

함수가 끝났을때 종료x 프로그램 종료때 소멸된다.

 

 

 

 

19-6 스택 영역

스택=콜스택

 

adder result -1.얘사라지고

num -2.얘사라짐

main -3.얘만 남음

 

 

 

 

19-7  힙 영역

  String str1,2는 전역변수 = 콜스택=스택영역

new 만 힙영역에 들어간다.

 

 

이런거 알아야 자식=( )부모 형변환 이해가능

자식부모형변환 관련 mommoo.tistory.com/51 참고하기

 

 

19-8 자바 가상머신의 인스턴스 소멸 시기

 

참조변수가 메모리에 올라간 상태인데 null을 넣어주면 객체관계끊어버리는 것. 따라서 인스턴스 접근 불가. 근데 왜 null로 해줌? 힙영역에 있는 인스턴스를 정리해주는게 JVM에있다. 필요없는데 기능을 가질필요도없으니 쓰레기 치워주는 가비지 컬렉션 객체를 JVM이 가지고있다.

메소드 나눠가지고 하는거 다 JVM이 한다.

객체를 사용하지 않겠다는 null표시는 가비지컬렉션으로 하여금 가비지컬렉션(gc)이 처리해도 좋다는 표시이다.

 

 

 

 

메모리관리는 상당히 중요하다!!!

 

 

 

19-9 Object 클래스

Object클래스(최고의 조상, 다형성 적용)에는 11개의 클래스가 존재한다.

 

 

19-10 Object 클래스의 finalize 메소드 -잘안씀

↑소멸시기 : 인스턴스 소멸 시 자동으로 호출이 된다 - 이것만 기억하기 꼭!

 

 

19-11 finalize 메소드의 오버라이딩 예 -실무에서는 사용안하는데 이해돕기위해 그냥 보자

Class Person extends Object{

 

finallize( )를 오버라이딩함. 

 

protected void finalize( ) throws Throwable { //

super.finalize( ); 를 왜해주냐 - 부모거 받았으니까 당연히

만약 안적어주면 소멸될때 함수 호출이 안된다.

 

// System.gc();

// System.runFinalization();

↑이런 시스템적인 코드는 실무에서 절.대. 쓰면안된다.

뒤에 있는 코드 난리남

 

 

 

 

 

19-12 인스턴스의 비교: equals 메소드

왼쪽거 오버라이드 안하면 어떻게되는지 알아보고싶으면? equals에서 f3찾아가보자

num2가 num1으로 갈수있는건 다형성(poly어쩌구)

 

equals로 오버리이딩 많이 함.

 

 

19-13 인스턴스의 비교: equals 메소드

equals는 함수오버라이딩해서 (부모는 자식거) 자기목적에 맞게끔 만들었기때문에 값이 같다.

함수오버라이딩했는지 어떻게 알까?? f3들어가보기

 

 

 

 

오늘의 문제

1.throws 에 대하여 설명하시오.

던져주는것. 

 예)
try {
md1();
} catch (IOException e) {
e.printStackTrace();

}
}

public static void md1() throws IOException {
md2();
}

public static void md2() throws IOException {

 

설명 :

md2()메소드에서 에러가 나면 md2()를 호출해준 md1()에 예외처리를 던지고 md1은 catch문에 예외처리를 던지고 catch문은 JVM에 예외처리를 던진다.

 

 

 


2.아래가 컴파일 에러가 나는 이유에 대하여 설명하시오.

try {
        	int num = 6 / 0;
        	
        	
		} catch (Exception e) {
			e.printStackTrace();
		} catch (InputMismatchException e) {
			e.printStackTrace();
		}

Exception은 예외처리에서 최고부모인데  다형성(Polymorphism)이 적용되어 부모가 자식보다 위에 쓰이게 되면 예외처리 자식인 InputMismatchException에 도달하지 못하여서 "Unreachable catch block for InputMismatchException." 이라는 경고문이 뜨면서 빨간줄이 그어진다.

 

3.try with resource 에 대하여 설명하시오.

rescources = 객체. 하나의 메모리

원래는 try-catch문에서 try뒤에 아무것도 쓰지 않는데

try뒤에 괄호를 넣어서 객체 생성해주면

굳이 .close를 쓰지않아도 try-catch문이 알아서 종료해준다.

(.close를 꼭써야하는 이유. 알수없는 에러가 일어날수도 있기때문예)

 

4.equals 함수에 대하여 설명하시오.

두 인스턴스를 비교해주는 함수이다.

주소값을 비교하지않고 출력한 String 값을 비교해준다.

하위 클래스에서 Override 하면 값을 비교하는 기능으로 사용할 수 있다.

 

이거 무조건 기억하기

**public boolean equals(Object obj) {

return (this == obj);

}

기능: this와 obj 를 비교해 서로 같은 객체를 가리키고 있는지 참조값을 비교해서 true or false로 리턴함

Object 클래스의 equals 함수를 사용하면 객체를 가리키는 주소값을 비교하는 것!!

 

 

 

 

5. 과일, 사과, 배, 포도를 표현한 클래스를 만들고 이들 간의 관계를 고려하여 하나의 클래스를 추상 클래스로 만들어 메소드 print()를 구현하고 다음과 같은 소스와 결과가 나오도록 클래스를 작성하시오.

- 소스

Fruit fAry[] = {new Grape(), new Apple(), new Pear());

for(Fruit f : fAry)

f.print();

-  결과

나는 포도이다.
나는 사과이다.
나는 배이다.

 

 

//풀이

package java_1216_;
//과일, 사과, 배, 포도를 표현한 클래스를 만들고 

//이들 간의 관계를 고려하여 하나의 클래스를 
//추상 클래스로 만들어 메소드 print()를 구현하고
//다음과 같은 소스와 결과가 나오도록 클래스를 작성하시오.

//나는 포도이다.
//나는 사과이다.
//나는 배이다.
public class FruitMain {
	public static void main(String[] args) {

		Fruit fAry[] = { new Grape(), new Apple(), new Pear() };

		for (Fruit f : fAry)
			
			f.print();
	}
}

abstract class Fruit {
	Fruit f;
	protected abstract void print();
	

}

class Grape extends Fruit {

	public Grape() {

	}

	@Override
	protected void print() {
		System.out.println("나는 사과이다.");
		
	}

}

class Apple extends Fruit {
	public Apple() {

	}

	@Override
	protected void print() {
		System.out.println("나는 포도이다");
	}
}

class Pear extends Fruit {
	public Pear() {

	}

	@Override
	protected void print() {
		System.out.println("나는 복숭아이다");
	}

}

 



6. 다음 조건을 만족하도록 클래스 Person과 Student를 작성하시오.
- 클래스 Person
* 필드 : 이름, 나이, 주소 선언
- 클래스 Student
* 필드 : 학교명, 학과, 학번, 8개 평균평점을 저장할 배열로 선언
* 생성자 : 학교명, 학과, 학번 지정
* 메소드 average() : 8개 학기 평균평점의 평균을 반환
- 클레스 Person과 Student 프로그램 테스트 프로그램의 결과 : 8개 학기의 평균평점은 표준입력으로 받도록한다.
이름 : 김다정
나이 : 20

주소 : 서울시 관악구
학교 : 동양서울대학교
학과 : 전산정보학과
학번 : 20132222

----------------------------------------

8학기 학점을 순서대로 입력하세요

1학기 학점  → 3.37
2학기 학점  → 3.89
3학기 학점  → 4.35
4학기 학점  → 3.76
5학기 학점  → 3.89
6학기 학점  → 4.26
7학기 학점  → 4.89
8학기 학점  → 3.89 

----------------------------------------

8학기 총 평균 평점은 4.0375점입니다.

 

//오류코드

package java_1216_;

import java.util.Scanner;

//- 클레스 Person과 Student 프로그램 테스트 프로그램의 결과 : 8개 학기의 평균평점은 표준입력으로 받도록한다. 
//이름 : 김다정 
//나이 : 20 
//
//주소 : 서울시 관악구 
//학교 : 동양서울대학교 
//학과 : 전산정보학과 
//학번 : 20132222 
//
//---------------------------------------- 
//
//8학기 학점을 순서대로 입력하세요 
//
//1학기 학점  → 3.37 
//2학기 학점  → 3.89 
//3학기 학점  → 4.35 
//4학기 학점  → 3.76 
//5학기 학점  → 3.89 
//6학기 학점  → 4.26 
//7학기 학점  → 4.89 
//8학기 학점  → 3.89  
//
//---------------------------------------- 
//
//8학기 총 평균 평점은 4.0375점입니다. 

class Person {
	protected String name;
	protected int age;
	protected String address;

	public Person(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}

	
}

class Student extends Person {
	private String school, depart;
	int id;
	private double Arr[];

	Student(String name, int age, String address, String school, String depart, int id) {
		super(name, age, address);

		this.school = school;
		this.depart = depart;
		this.id = id;

	}

	public void print() {
		System.out.println("이름 : " + name + "\n나이 : " + age + "\n주소 : " + address + "학교는 : " + school + "학과는 : "
				+ depart + "학번은 : " + id);
	}
	
	private static double average(Arr[] num) {

		System.out.println("8학기 학점을 순서대로 입력하세요 ");
		Scanner sc = new Scanner(System.in);
		double scr = sc.nextInt();
		int i;
		int[] num = new int[8];
		for (i = 1; i < num.length + 1; i++) {

			System.out.println(i + "번째 학점>>" + scr);
		}

		double sum = 0;
		for (i = 1; i < num.length + 1; i++)
			sum += num[i];

		System.out.println(num + "학기 총 평균 평점은 " + sum / i + "점입니다.");

	}

}

public class ScoreMain {
	public static void main(String[] args) {
		Student st = new Student("김다정", 20, "서울시 관악구", "동양서울대학교", "전산정보학과", 20132222);

		
		st.average();

	}

}

 

 

//정상 코드

package java_1217;

import java.util.Scanner;

class Person {
	protected String name;
	protected int age;
	protected String address;

	public Person(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}
}

class Student extends Person {
	private String school, depart;
	private int id;
	private double[] num = new double[8];

	Student(String name, int age, String address, String school, String depart, int id) {
		super(name, age, address);
		this.school = school;
		this.depart = depart;
		this.id = id;

	}

	public void print1() {
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
		System.out.println("주소 : " + address);
		System.out.println("학교는 : " + school);
		System.out.println("학과는 : " + depart);
		System.out.println("학번은 : " + id);
	}

	public void print2() {
		double sum = 0.0;

		Scanner sc = new Scanner(System.in);
		System.out.println("8학기 학점을 순서대로 입력하세요 ");

		double[] num = new double[8];
		for (int i = 0; i < num.length; i++) {
			System.out.print(i + 1 + "번째 학점>> ");
			num[i] = sc.nextDouble();
		
			sum += num[i];
		}
			System.out.println("8학기 총 평균 평점은 " + sum / num.length + "점입니다.");
		
		
	}
}

public class ScoreMain {
	public static void main(String[] args) {
		Student st = new Student("김다정", 20, "서울시 관악구", "동양서울대학교", "전산정보학과", 20132222);
		st.print1();
		st.print2();
		
	}

}



7.다음은 도형의 구성을 묘사하는 인터페이스이다.

 

interface Shape {
   final double PI = 3.14; // 상수
   void draw(); // 도형을 그리는 추상 메소드
   double getArea(); // 도형의 면적을 리턴하는 추상 메소드
   default public void redraw() { // 디폴트 메소드
      System.out.print("--- 다시 그립니다.");
      draw();
   }
}
//다음 main() 메소드와 실행 결과를 참고하여,
//인터페이스 Shape을 구현한 클래스 Circle를 작성하고 전체 프로그램을 완성하라.

public static void main(String[] args) {
   Shape donut = new Circle(10); // 반지름이 10인 원 객체
   donut.redraw();
   System.out.println("면적은 "+ donut.getArea());
}

 

 

//풀이

package java_1216_;

interface Shape {
	final double PI = 3.14; // 상수

	void draw(); // 도형을 그리는 추상 메소드

	double getArea(); // 도형의 면적을 리턴하는 추상 메소드

	default public void redraw() { // 디폴트 메소드
		System.out.print("--- 다시 그립니다.");
		draw();
	}
}

class Circle implements Shape{
private double i;
	public Circle(double i) {
		this.i = i;
	}

	@Override
	public void draw() {
		
		
	}

	@Override
	public double getArea() {
	
		return i*i*PI;
	}
	
}
// 다음 main() 메소드와 실행 결과를 참고하여,
// 인터페이스 Shape을 구현한 클래스 Circle를 작성하고 전체 프로그램을 완성하라.
public class ShapeMain {
	public static void main(String[] args) {
		Shape donut = new Circle(10); // 반지름이 10인 원 객체
		donut.redraw();
		System.out.println("면적은 " + donut.getArea());
	}

}

 


8.
다음 main() 메소드와 실행 결과를 참고하여, 문제 7의 Shape 인터페이스를 구현한 클래스 Oval, Rect를 추가 작성하고 전체 프로그램을 완성하라.

public static void main(String[] args) {
   Shape[] list = new Shape[3]; // Shape을 상속받은 클래스 객체의 레퍼런스 배열
   list[0] = new Circle(10); // 반지름이 10인 원 객체
   list[1] = new Oval(20, 30); // 20x30 사각형에 내접하는 타원
   list[2] = new Rect(10, 40); // 10x40 크기의 사각형
   for(int i=0; i<list.length; i++) list[i].redraw();
   for(int i=0; i<list.length; i++) System.out.println("면적은 "+ list[i].getArea());
}
--- 다시 그립니다.반지름이 10인 원입니다.
--- 다시 그립니다.20x30에 내접하는 타원입니다.
--- 다시 그립니다.10x40크기의 사각형 입니다.
면적은 314.0
면적은 1884.0000000000002
면적은 400.0

 

//풀이

package java_1216_;

interface Shape {
	final double PI = 3.14; // 상수

	void draw(); // 도형을 그리는 추상 메소드

	double getArea(); // 도형의 면적을 리턴하는 추상 메소드

	default public void redraw() { // 디폴트 메소드
		System.out.print("--- 다시 그립니다.");
		draw();
	}
}

class Circle implements Shape {
	private double i;

	public Circle(double i) {
		this.i = i;
	}

	@Override
	public void draw() { // 도형을 그리는 추상 메소드
		System.out.println("반지름이" + i + "인 원입니다.");

	}

	@Override
	public double getArea() {// 도형의 면적을 리턴하는 추상 메소드

		return i * i * PI;
	}

}

class Oval implements Shape {
	private int i, j;

	public Oval(int i, int j) {
		this.i = i;
		this.j = j;
	}

	@Override
	public void draw() { // 도형을 그리는 추상 메소드
		System.out.println(i + "x" + j + "에 내접하는 타원입니다.");

	}

	@Override
	public double getArea() {// 도형의 면적을 리턴하는 추상 메소드

		return i * j * PI;
	}

}

class Rect implements Shape {
	private int i, j;

	public Rect(int i, int j) {
		this.i = i;
		this.j = j;
	}

	@Override
	public void draw() { // 도형을 그리는 추상 메소드
		System.out.println(i + "x" + j + "크기의 사각형 입니다.");

	}

	@Override
	public double getArea() {// 도형의 면적을 리턴하는 추상 메소드

		return i * j;
	}

}

// 다음 main() 메소드와 실행 결과를 참고하여,
// 인터페이스 Shape을 구현한 클래스 Circle를 작성하고 전체 프로그램을 완성하라.
public class ShapeMain {
	public static void main(String[] args) {
		Shape[] list = new Shape[3]; // Shape을 상속받은 클래스 객체의 레퍼런스 배열
		list[0] = new Circle(10); // 반지름이 10인 원 객체
		list[1] = new Oval(20, 30); // 20x30 사각형에 내접하는 타원
		list[2] = new Rect(10, 40); // 10x40 크기의 사각형
		for (int i = 0; i < list.length; i++)
			list[i].redraw();
		for (int i = 0; i < list.length; i++)
			System.out.println("면적은 " + list[i].getArea());
	}

}

728x90

댓글