package ex0728;

// import java.util.Arrays;

public class Ex11_generic {
	public static void main(String[] args) {
		Object[] obj = new Object[5];

		// Object는 모든 클래스 객체를 참조할 수 있다. (up casting)
		obj[0] = new String("서울");
		obj[1] = new String("부산");
		obj[2] = new Integer(30);
		obj[3] = new Integer(50);
		obj[4] = new String("인천");

		// Arrays.sort(obj); // ClassCastException 런타임 오류

		// String s = (String)obj[2]; // ClassCastException 런타임 오류
		if (obj[1] instanceof String) { // obj[2] 너 String 형이니?
			String s = (String) obj[1]; // 스트링 형이면 다운캐스팅하고
			System.out.println(s + ":" + s.length()); // 출력하고 : 길이도 출력해
		}

		for (Object o : obj) {
			System.out.println(o);
		}

	}
}

Object는 모든 클래스들의 조상이므로 (시조라고 해야하나 ㅋㅋ)

자식들은 Object클래스로 up casting이 가능하다. 지금 이 코드는 숫자나 문자열 모두 그냥 Object에 넣었다.

이럴 경우 데이터타입에 관계없이 모든 것을 넣을 수 있다.

하지만 자료형이 다 제각각이므로 Arrays.sort(obj); 과 같은 메소드를 사용하면 런타임 오류가 발생한다. 

 

Integer 30을 강제로 캐스팅 하면 ClassCastException 이라는 런타임 오류가 발생한다. 그래서 A instanceof B 를 써서 배열A에 들어가 있는 데이터타입이 B 이면 강제로 다운캐스팅(다운캐스팅은 업캐스팅한 것만 가능)하고 출력하라고 밑에서 if문을 쓴 것이다.


package ex0728;

public class Ex12_generic {
	public static void main(String[] args) {
		Test2 t1 = new Test2();
		// t1.set(new String("서울"));
		t1.set("서울");
		String s = (String)t1.get();
		System.out.println(s);
		
		// Integer i1 = (Integer) t1.get(); // ClassCastException 런타임 오류.
		
		Test2 t2 = new Test2();
		t2.set(30);
		Integer i2 = (Integer)t2.get();
		System.out.println(i2);
	}
}

class Test2 {
	private Object ob;
	
	public void set(Object ob) {
		this.ob = ob;
	}
	
	public Object get() {
		return ob;
	}
}

t1의 객체는 String형을 저장하고

t2의 객체는 Integer형을 저장했다.

그냥

System.out.println(t1.get());
System.out.println(t2.get());

이면 상관없지만

s, i2에 넣을 때는 s의 데이터타입인 String으로 다운캐스팅 i2의 데이터타입인 Integer로 다운캐스팅을 해야 한다.

 


본격적으로 Generic에 대해 알아보자.

 

다양한 타입의 객체를 다루는 클래스나 인터페이스에서 사용할 데이터 타입을 인스턴스를 생성할 때 결정하는 것으로 JDK 5.0부터 지원한다.

  • 성능 저하를 유발하는 강제 캐스팅을 줄일 수 있다.
  • 컴파일 할 때 타입 오류를 체크하므로 객체 타입의 안정성을 높인다.
  • 반복적인 코드를 줄일 수 있으며, 재사용성 증가로 유지보수가 편리하다.

 

package ex0728;

public class Ex13_generic {
	public static void main(String[] args) {
		Test3<String> t1 = new Test3<String>();
		t1.set("서울");
		// t1.set(50); // 컴파일 오류
		String s = t1.get();
		System.out.println(s);
		
		// Integer i1 = (Integer)t1.get(); // 컴파일 오류. 미연에 방지 할 수 있다!
		
		Test3<Integer> t2 = new Test3<>(); // new 뒤에 <>에서는 자료형 생략가능. new Test3<Integer> 에서 Integer생략
		t2.set(30);
		Integer n = t2.get();
		System.out.println(n);
		
/*		
		Test3 t3 = new Test3(); // 가능하지만 경고 발생. 제너릭은 Object로 처리.
		t3.set("서울");
		t3.set(50);
*/
		
		
	}
}

class Test3<T> { // <> 안에는 마음대로 이름을 줄 수 있다. 
	private T t; // T에 자료형은 String, Integer, Long ...등이 올 수 있음. 아직 정해지지 않았다.
	public void set(T t) {
		this.t = t;
	}
	
	public T get() {
		System.out.println(t.getClass()); // 무슨 클래스인지 볼 수 있다.
		return t;
	}
}

객체를 생성할때 <> 안에 어떤 데이터타입만 저장할 것인지 설정을 해서 생성할 수 있다.

Test3<String> t1 = new Test3<String>();

 

t1.set(50); 으로 주면 컴파일 오류가 생기기 때문에 안정적으로 코딩할 수 있다.

 

제네릭을 설정하지 않고 그냥 

Test3 t3 = new Test3(); 으로 객체를 생성하면 경고가 발생한다. 이때 제네릭은 Object로 처리되기 때문에 

t3.set("서울");

t3.set(50); 

모두 넣을 수 있다. 하지만 비추천.

 

제네릭을 만들 때 <> 안에 마음대로 이름을 줄 수 있으나 관습적으로 대문자 알파벳 한 문자를 사용하고

E : Element

K : Key

N : Number

T : Type

V : Value

S, U, V : 2nd, 3rd, 4th types..

으로 사용한다.

 

마지막에 확인해보면 t1의 클래스는 <String>으로 줬기 때문에 String으로 뜨고, t2는 Integer로 준 것을 확인 할 수 있다.


package ex0728;

public class Ex14_generic {
	public static void main(String[] args) {
		Test4<String, Integer> ob = new Test4<>();
		
		ob.set("자바", 100);
		ob.print();
		
		ob.set("스프링", 200);
		ob.print();
	}
}

class Test4<T, U> {
	private T t;
	private U u;
	
	public void set(T t, U u) {
		this.t = t;
		this.u = u;
	}
	
	public void print() {
		System.out.println("T : "+t.getClass().getName()+", "+t);
		System.out.println("U : "+u.getClass().getName()+", "+u);
	}
	
	
}

제네릭 클래스에 멀티 타입 파라미터를 준 경우이다. 만들때 <String, Integer>라고 했으니 T의 자료형은 String형이되고 U의 자료형은 Integer형이 된다.


package ex0728;

public class Ex15_generic {
	public static void main(String[] args) {
		Test5<Integer> ob = new Test5<>();
		ob.set(30);
		Integer i = ob.get();
		System.out.println(i);
		
		// Test5<String> ob2 = new Test5<>(); // 컴파일 오류 발생.
		// Number를 상속받은 class가 아니기 때문이다.
		
	}
}

// 제한된(한정된) 타입 파라미터(bounded type parameter)
// Number를 상속받은 클래스만 가능 (Integer, Long, Double ...)
class Test5<T extends Number> {
	private T t;
	public void set(T t) {
		this.t=t;
	}
	
	public T get() {
		return t;
	}
}

제한된 타입 파라미터만을 받도록 설정한 제네릭 클래스.

T extends Number를 통해 Number를 상속받았기 때문에 그 클래스에 포함되는 것들만 파라미터로 받을 수 있다.

package ex0728;

public class Ex16_genericMethod {
	public static void main(String[] args) {
		Test6 t = new Test6();
		
		t.print("자바");
		t.print(20);
		
		t.disp(30);
		// t.disp("자바"); // 컴파일 오류
	}
}

// generic Method 
class Test6 {
	public <U> void print(U u) {
		System.out.println(u.getClass().getName() + ", " + u);
	}

	public <U extends Number> void disp(U u) {
		System.out.println(u.getClass().getName() + ", " + u);
	}
}

제네릭 메소드 타입 파라미터를 하나 이상 갖는 메소드를 말한다.

선언 방법은 리턴 타입 앞에 <> 기호를 추가하고 <> 기호 안에 타입 파라미터를 기술 한 후 리턴 타입과 매개 변수타입에서 타입 파라미터를 사용한다.

disp(U u) 메소드의 경우 받는 자료형을 Number를 상속받은 것들만 가능하게 설정했으므로 

t.disp("자바"); 의 경우 컴파일 오류이다.

package ex0728;

public class Ex17_generic {
	public static void main(String[] args) {
		TestImpl7<Integer> ob1 = new TestImpl7<>();
		ob1.print(10);
		
		DemoImpl7 ob2 = new DemoImpl7();
		ob2.print("자바");
		
	}
}

// 제네릭 인터페이스
interface Test7<T> {
	public void print(T t);
}

// 구현 클래스-1
class TestImpl7<T> implements Test7<T> {
	@Override
	public void print(T t) {
		System.out.println(t);
		
	}
	
}

// 구현 클래스-2
class DemoImpl7 implements Test7<String> {
	@Override
	public void print(String t) {
		System.out.println(t);
	}
	
}​

제네릭 인터페이스를 구현할 때 위의 2가지 방법으로 구현할 수 있다.

1의 경우 자료형을 객체를 생성할 때 결정한 방법이고

2의 경우 구현 클래스에서 자료형을 결정한 방법이다.

 

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0729_ConsoleEx_콘솔 입력  (0) 2021.07.29
0729_Ex01~Ex05_Generic  (0) 2021.07.29
0728_Ex01~Ex03_exception : 예외처리  (0) 2021.07.29
0727_패키지  (0) 2021.07.27
0727_Ex06~Ex08_enum : 열거형  (0) 2021.07.27
package ex0728;

public class Ex01_exception {
	public static void main(String[] args) {
		User1 ob = new User1();
		
		try {
			ob.set("김자바", -5);
			// ob.set(null, 10);
			System.out.println(ob.getName() + ":" + ob.getAge());
		} catch (Exception e) {
			System.out.println(e.toString());
		}

		
	}
}

class User1 {
	private String name;
	private int age;

	public void set(String name, int age) throws Exception{
		try {
			setName(name);
			setAge(age);
		} catch (Exception e) {
			// System.out.println(e.toString());
			// throw new Exception("값을 설정하지 못했습니다."); // 새로운 예외를 발생
			
			throw e; // 예외를 다시 던짐
		}
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) throws Exception {
		if(name == null)
			throw new Exception("이름은 null이 될 수 없습니다.");
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) throws Exception {

		if (age < 0)
			throw new Exception("나이는 0이상입니다.");

		this.age = age;
	}

}

package ex0728;

import java.util.Scanner;

public class Ex02_exception {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		User2 ob = new User2();

		try {
			System.out.print("이름 ? ");
			ob.setName(sc.next());
			System.out.print("나이 ? ");
			ob.setAge(sc.nextInt());
			
			System.out.println(ob.getName()+"+"+ob.getAge());
		} catch (Exception e) {
			System.out.println("입력 오류 입니다.");
		} finally { // finally 에서 자원을 닫아주어야 한다.
			sc.close();
		}
		System.out.println("end...");
	}
}

class User2 {
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) throws Exception {
		if(name.length()<2)
			throw new Exception("이름은 두자 이상입니다.");
		
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) throws Exception {

		if (age < 0)
			throw new Exception("나이는 0이상만 가능 합니다.");

		this.age = age;
	}

}

 

여기서는 예외가 발생하면 "입력 오류 입니다."를 출력한다. 

예외가 발생했을 때 만들었던 예외를 출력하려면

System.out.println(e.toString()); 이거를 추가해야지 왜 예외가 발생했는지 알려줌.

package ex0728;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Ex03_exception {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		User3 ob = new User3();

		try {
			System.out.print("이름 ? ");
			ob.setName(sc.next());
			System.out.print("나이 ? ");
			ob.setAge(sc.nextInt());
			
			System.out.println(ob.getName()+"+"+ob.getAge());
		} catch (InputMismatchException e) {
			System.out.println("숫자만 입력 가능합니다...");
		} catch (NameValidException e) {
			System.out.println("이름은 두자 이상이어야 합니다...");
		} catch (AgeValidException e2) {
			System.out.println("나이는 0이상 입니다...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally { // finally 에서 자원을 닫아주어야 한다.
			sc.close();
		}
		System.out.println("end...");
	}
}

// 사용자 정의 예외 클래스(checked exception)
class NameValidException extends Exception {
	private static final long serialVersionUID = 1L; // 직렬화

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

class AgeValidException extends Exception {
	private static final long serialVersionUID = 1L;

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

class User3 {
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) throws NameValidException {
		if(name.length()<2)
			throw new NameValidException("이름은 두자 이상입니다.");
		
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) throws AgeValidException {

		if (age < 0)
			throw new AgeValidException("나이는 0이상만 가능 합니다.");

		this.age = age;
	}

}

checked exception은 exception의 자식 클래스 이므로 사용자 정의 예외 클래스를 만드려면 Exception을 상속받아서 만들어야 한다. 직렬화의 경우 아직 배우지 않았으나 사용자 정의 예외 클래스를 만들 때는 옆에 느낌표를 눌러서 해결해줘야한다. 

굳이 catch 블록에

System.out.println("이름은 두자 이상이어야 합니다..."); 를 쓰지 않고

System.out.println(e.toString()); 를 넣어서 해도 될 것 같다.

throws
 : 메소드 시그니처(선언부분)에 선언
 : 메소드를 호출하는 곳에서 예외처리를 하도록 설정
 
throw
 : 예외를 강제로 발생 시킴

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0729_Ex01~Ex05_Generic  (0) 2021.07.29
0728_Ex11~Ex17_generic : 제네릭  (0) 2021.07.29
0727_패키지  (0) 2021.07.27
0727_Ex06~Ex08_enum : 열거형  (0) 2021.07.27
0727_Ex05_중첩 인터페이스  (0) 2021.07.27

==========================패키지
커맨드창에
-- 자바 컴파일(모든 자바 파일 컴파일. 자동으로 패키지를 폴더로 생성)
javac -d  .    *.java
하면
패키지에 써져있는 순서대로 폴더가 생기고 그 안에 컴파일된 class파일이 생김.

-- 자바 class 파일 압축 => jar
jar  cvf  my.jar  com
새로운 아카이브 파일을 만들겠다.c 압축하면서 화면상에 보여줘 v. 압축화일 이름설정f.

-- 클래스가 존재하는 파일을 설정하여 컴파일 및 실행
javac -classpath  my.jar  UserApp.java 

java -classpath   .;my.jar   UserApp

// 이클립스에서는 클릭만하면 되는데 cmd에서는 어떻게 이루어지는지 확인함!

enum 타입이란?

  • 변수가 미리 정의된 상수 세트가 될 수 있도록 하는 특수 데이터 유형(특수한 형태의 class)이다.
  • 열거형은 enum 키워드를 사용하여 정의한다.
  • new를 사용하여 객체를 생성할 수 없다.
package ex0727;

public class Ex06 {
	public static void main(String[] args) {
		// 열거형 상수의 기수(선언 위치) 출력
		for(Color c : Color.values()) {
			System.out.println(c+" -> " + c.ordinal());
		}
		// System.out.println(Color.RED == 0); // 컴파일 오류. C언어는 0임 (True)
		System.out.println();
		
		
		Test6 ob = new Test6();
		System.out.println(ob.getColor()); // RED 출력
		
		ob.setColor(Color.BLUE);
		Color color = ob.getColor();
		
		// case에서는 enum은 enum명 생략 가능(Color 생략 가능)
		switch(color) {
		case RED : System.out.println("red"); break;
		case GREEN : System.out.println("greed"); break;
		case BLUE : System.out.println("blue"); break;
		}
	}
}

enum Color {
	RED, GREEN, BLUE
}	

class Test6 {
	private Color color = Color.RED;
	
	public void setColor(Color color) {
		this.color = color;
	}
	
	public Color getColor() {
		return color;
	}
}

ordinal 이란 메소드는 열거형에 있는 값들을 순서대로 return해준다. 여기에서 RED가 0 이라고 반환했지만 0과 같지는 않다. 

package ex0727;

public class Ex07 {
	public static void main(String[] args) {
		System.out.println(City.SEOUL);
		// toString() 이 재정의 되어 있지 않으면 SEOUL 출력
		System.out.println("서울 : "+City.SEOUL.getCount());
		
		System.out.println("\n전체 리스트...");
		for(City c : City.values()){
			System.out.println(c.getName()+" : "+c.getCount());
		}
		
	}
}

// 열거형 상수에 값 할당 - 생성자를 만들어야 함
enum City {
	SEOUL("서울", 1000),
	BUSAN("부산", 350),
	INCHEON("인천", 330);
	
	private String name;
	private int count;
	
	// 생성자는 private만 가능. 생략해도 private
	private City(String name, int count) {
		this.name = name;
		this.count = count;
	}

	public String getName() {
		return name;
	}

	public int getCount() {
		return count;
	}
	
	@Override
	public String toString() {
		return this.name +"  인구 : "+this.count+"만명";
	}
}

package ex0727;

public class Ex08 {
	public static void main(String[] args) {
		double a;
		
		a = Operation.PLUS.eval(10, 5);
		System.out.println(a);
		
		double x = 10, y = 5;
		for(Operation op : Operation.values()) {
			System.out.printf("%.1f %s %.1f = %.1f\n", x, op, y, op.eval(x, y));
		}

	}
}

// 열거형 상수 - 메소드 정의. 추상 메소드가 선언되어야 함.
enum Operation {
	// 재정의 하는 꼴!
	PLUS { public double eval(double x, double y) {return x + y; } },
	MINUS { public double eval(double x, double y) {return x - y; } },
	TIMES { public double eval(double x, double y) {return x * y; } },
	DIVIDE { public double eval(double x, double y) {return x / y; } };
	
	public abstract double eval(double x, double y); // 이게 꼭 있어야 함!
}

 

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0728_Ex01~Ex03_exception : 예외처리  (0) 2021.07.29
0727_패키지  (0) 2021.07.27
0727_Ex05_중첩 인터페이스  (0) 2021.07.27
0727_Ex03_anonymous class : 익명클래스  (0) 2021.07.27
0727_Ex01~Ex02_중첩 클래스  (0) 2021.07.27
package ex0727;

public class Ex05 {
	public static void main(String[] args) {
		Button.OnClickListener listener = new Button.OnClickListener() {
			@Override
			public void onClick() {
				System.out.println("클릭 !!!");
			}
		};
		
		listener.onClick();
		
	}
}

// 중첩 인터페이스
class Button {
	public interface OnClickListener {
		public void onClick();
	}
}

객체 생성할때 뜨는거 컨트롤 스페이스 바에서 바로 밑에 선택하면 알아서 override가 나옴.

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0727_패키지  (0) 2021.07.27
0727_Ex06~Ex08_enum : 열거형  (0) 2021.07.27
0727_Ex03_anonymous class : 익명클래스  (0) 2021.07.27
0727_Ex01~Ex02_중첩 클래스  (0) 2021.07.27
0727_Ex111~116_throws : Checked, Unchecked ...  (0) 2021.07.27
package ex0727;

public class Ex03 {
	public static void main(String[] args) {
		User3 ob = new User3();
		ob.sub();
		ob.disp();
	}
}

interface Test3 {
	public void print();
}

class User3 {
	public void sub() {
		// anonymous class 익명클래스
		// Test3 t = new Test3(); // 컴오류. 인터페이스는 객체 생성 불가
		// 익명 클래스는 컴파일하면 User3$1.class 이름의 클래스 파일이 생성(뒤 번호는 순서)
		Test3 t = new Test3() {
			// 익명 클래스에서 인터페이스 메소드 재정의
			@Override
			public void print() {
				System.out.println("sub...");
				
			}
		};
		t.print();
		
	}
	public void disp() {
		Test3 t = new Test3() {
			@Override
			public void print() {
				System.out.println("disp...");
			}
		};
		t.print();
	}
}

package ex0727;

public class Ex04 {

	public static void main(String[] args) {
		Object ob1 = new Object();
		System.out.println(ob1); // 클래스명@해쉬코드
		
		Object ob2 = new Object() {
			@Override
			public String toString() {
				// TODO Auto-generated method stub
				return "익명 클래스로 재정의...";
			}
		};
		System.out.println(ob2);

	}

}

익명 클래스 ?

  • 클래스 또는 인터페이스에 대한 객체를 생성하면서 바로 클래스 또는 인터페이스를 정의하는 클래스 
  • 정의하는 부분과 생성하는 부분이 하나로 묶어져 new수식이 있는 곳에서 바로 클래스를 정의하거나 인터페이스를 구현

'쌍용강북교육센터 > 7월' 카테고리의 다른 글

0727_Ex06~Ex08_enum : 열거형  (0) 2021.07.27
0727_Ex05_중첩 인터페이스  (0) 2021.07.27
0727_Ex01~Ex02_중첩 클래스  (0) 2021.07.27
0727_Ex111~116_throws : Checked, Unchecked ...  (0) 2021.07.27
0727_Ex110_tryResource  (0) 2021.07.27

 

package ex0727;

public class Ex01 {
	public static void main(String[] args) {
		// 외부에서 중첩 클래스의 객체를 생성
		Test1.User1 u = new Test1.User1();
		u.write();
		
	}
}

class Test1 {
	int a = 10;
	static int b = 0;
	
	// static 중첩 클래스
	// 외부 클래스(Test1)의 객체 생성과 상관 없이 객체를 생성하여 사용할 수 있는 클래스
	// 컴파일하면 Test1$User1.class
	static class User1 {
		int x = 100;
		
		public void write() {
			// System.out.println(a); // 컴오류.
			System.out.println(b);
		}
		
		public void disp() {
			Test1 t = new Test1();
			System.out.println(t.a);
			t.print();
		}
	}
	
	public void print() {
		System.out.println(a + ", "+ b);
	}
	
	public static void sub() {
		// System.out.println(a); // 컴오류. 클래스 메소드는 인스턴스 변수 접근 불가
		System.out.println(b);
	}
}

package ex0727;

public class Ex02 {
	public static void main(String[] args) {
		// 내부 클래스는 외부에서 단독으로 객체 생성이 불가능
		// Test2.User2 ob = new Test2.User2(); // 컴오류
		
		// 내부 클래스는 외부 클래스의 객체를 생성후에 생성된 객체를 이용하여 생성
		// 내부 클래스는 외부 클래스 내(메소드)에서 사용할 목적으로 만듦(보안에 유리)
		Test2 ob = new Test2();
		Test2.User2 uu = ob.new User2();
		uu.write();
	}
}

class Test2 {
	int a = 10;
	static int b = 20;
	
	// 내부 클래스(member class)
	// 외부 클래스(Test2) 객체가 생성 되어야 객체를 생성할 수 있는 클래스
	class User2 {
		int x = 100;
		
		public void write() {
			// 외부 클래스의 인스턴스 변수나 인스턴스 메소드 접근 가능
			System.out.println(a+", " +b +", "+x);
		
			// print(); // 가능
		}
	}
	
	public void print() {
		System.out.println(a+", "+b);
	}
	
	public void sub() {
		// 메소드 내에서 내부 클래스의 객체 생성 및 활용 
		User2 u = new User2();
		u.write();
	}
	
}

package ex0727;

public class Ex111_throws {

	public static void main(String[] args) {
		User11 u = new User11();
		
		u.setValue(-5);
		int n = u.getValue();
		System.out.println(n);

	}

}

// 잘못 작성된 클래스
class User11 {
	private int value;

	public void setValue(int value) {
		if (value < 0)
			return;

		this.value = value;
	}
	
	public int getValue() {
		return value;
	}
}

package ex0727;

public class Ex112_throwsChecked {

	public static void main(String[] args) {
		User12 u = new User12();
		
		try {
			u.setValue(-5);
			int n = u.getValue();
			System.out.println(n);
		} catch (Exception e) {
			// e.printStackTrace();
			System.out.println(e.toString());
		}
		System.out.println("end...");

	}

}

class User12 {
	private int value;

	public void setValue(int value) throws Exception { // 메소드를 호출하는 곳에서 catch하도록 설정
		if (value < 0) {
			// 강제로 checked exception을 발생 시킴
			throw new Exception("0 이상만 가능합니다."); // 예외를 발생시키는 것
		}

		this.value = value;
	}
	
	public int getValue() {
		return value;
	}
}

package ex0727;

public class Ex113_throws {

	public static void main(String[] args) throws Exception { // throws : 메소드를 호출한 곳에서 예외를 처리하도록  
	
		User13 ob = new User13();
		
		// 이곳에서 try~catch로 예외를 catch하지 않고 main()을 호출하는 곳에서 예외 처리하도록 설정
		
		// 위처럼 main() 메소드에서 throws 할 경우 예외가 발생하면
		// 		프로그램은 비 정상 종료된다. main()에서는 하면 안된다!!
		ob.setValue(-5);
		
		int n = ob.getValue();
		System.out.println(n);
		
		System.out.println("end...");

	}

}

class User13 {
	private int value;

	public void setValue(int value) throws Exception { // 메소드를 호출하는 곳에서 catch하도록 설정
		if (value < 0) {
			// 강제로 checked exception을 발생 시킴
			throw new Exception("0 이상만 가능합니다."); 
		}

		this.value = value;
	}
	
	public int getValue() {
		return value;
	}
}

package ex0727;

public class Ex114_throws {

	public static void main(String[] args) { 
		User14 ob = new User14();
	
		ob.setValue(-5);
		
		int n = ob.getValue();
		System.out.println(n);
		
		System.out.println("end...");

	}

}

class User14 {
	private int value;

	public void setValue(int value) { 
		
		try {
			if (value < 0) {
				throw new Exception("0 이상만 가능합니다."); 
			}
			
			this.value = value;
			
		} catch (Exception e) {
			// 위에서 throw new Exception("") 한 예외를 이곳에서 catch함
			System.out.println(e.toString());
		}
	}
	
	public int getValue() {
		return value;
	}
}

package ex0727;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Ex115_throws {
	public static void main(String[] args) {
		User15 ob = new User15();
		
		ob.input();
		ob.input();

	}
}

class User15 {
	private Scanner sc = new Scanner(System.in);

	public void input() {
		String name, tel;
		int kor, eng;

		try {
			System.out.print("이름 ? ");
			name = sc.next();

			System.out.print("국어 ? ");
			kor = inputScore();

			System.out.print("영어 ? ");
			eng = inputScore();

			System.out.print("전화번호 ? ");
			tel = sc.next();

			System.out.println(name + "," + kor + ":" + eng + ":" + tel);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		System.out.println("------------------------------");
	}

	// 점수를 입력 받는 메소드
	private int inputScore() throws Exception { // 메소드를 호출하는 곳에서 예외처리하도록 설정
		int s = 0;

		try {
			s = sc.nextInt();
			if (s < 0 || s > 100) {
				// 강제로 checked exception을 발생 시킴
				throw new Exception("점수는 0~100 사이만 가능합니다.");
			}
		} catch (InputMismatchException e) {
			// System.out.println("숫자만 입력 가능 합니다.");
			
			// 문제가 있는 데이터를 읽어서 버림(없으면 이상한 현상이 발생 됨.)
			sc.nextLine();
			
			// 강제로 checked exception을 발생 시킴
			throw new Exception("점수는 숫자만 입력 가능합니다.");
		}

		return s;
	}
}

package ex0727;

public class Ex116_throwUnchecked {
	public static void main(String[] args) {
		User16 u = new User16();
/*		
		u.setValue(-5);
			// value가 0보다 적어 RuntimeException이 발생.
			// 예외를 처리하지 않아 프로그램은 이곳에서 비정상적인 종료
		int n = u.getValue();
		System.out.println(n);
		System.out.println("end...");
*/
		
		try {
			u.setValue(-5);
			int n= u.getValue();
			System.out.println(n);
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	
		System.out.println("end...");
		
	}
}

class User16 {
	private int value;

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		if (value < 0) {
			// 숫자가 음수인 경우 RuntimeException 예외를 발생 시킴
			// RuntimeException은 unchecked exception으로 반드시 catch할 필요가 없다.
			throw new RuntimeException("0이상만 가능합니다.");
		}
	}
	
}

+ Recent posts