import static java.lang.System.out;
import static java.lang.Integer.parseInt; //주의할 점. 1. parseInt는 메소드임에도 ()를 붙이지 않는다.
public class PackageImportDemo{
public static void main(String[] args) {
java.lang.System.out.println("Hello"); //풀네임. 그러나 java lang을 안써줘도 되기에
System.out.println("Hello");
out.println("Hello"); //위에 import해주어 짧게 써줄 수 있다.
//int result = java.lang.Integer.parseInt("5"); //java.lang은 생략.
int result = parseInt("5"); //위에 import해주어 짧게 써줄수 있다.
}
//static int parseInt(String str){} //2.parseInt가 이름 충돌이 나는 것을 조심해야함.
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
AccessModifierDemo 4가지
public 만 보인다.
protected - 부모 자식 관계가 아니라서 보이지 않는다.
default - 같은 폴더에 위치하지 않아서 보이지 않는다.
package com.naver.libs.HR;
public class Insa {
private int num = 10;
double avg = 89.5;
protected char grade = 'A';
public String name = "Sally";
}
import com.naver.libs.HR.Insa;
public class AccessModifierDemo extends Insa {
public static void main(String[] args) {
AccessModifierDemo amd = new AccessModifierDemo();
amd. //까지 쓰면 name 과 grade까지만 쓸 수 있다. (부모자식관계이기 때문에)
}//만일 부모자식관계가아니고, Insa를 메모리에올리면 오직 public인 name만 접근 가능하다.
}
------
여기서 class의 접근제한자는 두개밖에 없다. class Insa 와 public class Insa만 쓸 수 있다. private과 protected는 사용 불가하다.
폴더안에서 접근하려면 default, 밖에서 접근하려면 public. 권한은 항상 제한해야하므로, public default 사용이 둘다 가능하면 default를 사용한다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
//static variable
public class StaticDemo {
public static void main(String[] args) {
Demo [] array = new Demo[3];
for(int i = 0 ; i < array.length; i++)
array[i] = new Demo();
for(Demo d : array)
System.out.println(d);
}
}
public class Demo {
int su;
static int num;
public Demo(){
this.su++;
num = this.su;
}
@Override
public String toString(){
return String.format("su = %d, num = %d\n", su, num);
}
}
출력:
su = 1, num = 1
su = 1, num = 1
su = 1, num = 1
new Demo로 항상 초기화된 값을 가지고 시작한다.
------여기서 Demo를 아래와 같이 바꿔주면
public Demo(){
this.su++;
num++;
}
출력:
su = 1, num = 3
su = 1, num = 3
su = 1, num = 3
num은 static이기 때문에 저장되는 위치가 다르다. 값이 변하면 변한 값을 계속 가지고 있는다. 그래서 마지막 값인 3을 계속 가지고 출력한다.
-----------------------------------------------
//public method
public class StaticDemo1 {
private static int num = getNum(); //메인보다 먼저 실행되어 num의 초기화 실행.
private static int getNum(){
System.out.println("나는 스태틱 메소드");
return 100;
}
public static void main(String[] args) {
System.out.println("나는 메인 메소드");
System.out.println("num = " + num);
}
}
//static method를 쓰는 이유는 주소없이 접근하기 위해서이다.
출력:
나는 스태틱 메소드
나는 메인 메소드
num = 100
------------------------------------------------
static initializers
public class StaticDemo2 {
private int num; //member variable //생성자가 num을 초기화 시켜준다.
private static double avg; //static variable
{ //member initialization block
num = 100;
System.out.println("Called \"member initialization block\"");
}
static { //static initializer //두번 호출 할 수없다.
avg = 89.5;
System.out.println("Called \"static initializer\"");
}
public static void main(String[] args) {
System.out.println("Called \"main method\"");
StaticDemo2 sd = new StaticDemo2(); //추가
}
}
//static variable이 가장먼저 메모리에 올라온다. 그래서 static initializer가 가장 먼저 실행된다.
//member initialization block 은 실행되지 않았는데 이것을 실행되게 하려면 생성자를 써줘야한다. 그래서 main의 2번째 줄을 추가해줬다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Final
//final variable --> constant
public class FinalDemo {
private final int NUM; //member constant
private static final double PI; //static constant
static{ //static initializer
PI = 3.141596; ////스태틱 상수 초기화
}
/*public FinalDemo(){ //constructor
this.NUM = 10000; //멤버상수의 초기화
}*/
//위 혹은 아래 중 하나로 멤버상수를 초기화 시켜줌.
{ //member initializer
this.NUM = 10000;
}
public static void main(String[] args) {
final String name = "Sally"; //local constant
}
}
-------------------
final을 method에 쓸 때
public class FinalDemo1 {
public static void main(String[] args) {
/*Bumo b = new Jasik();
b.display();*/ //부모의 display method를 final로 해주어서 이런식으로 만들어주면 자식의 display 메소드를 사용하지 못한다.
Jasik ja = new Jasik(); //상속의 기능을 이용하여 자식을 통하여 부모의 display, 자식의 display 메소드를 접근 가능하게한다.
ja.display(); ja.display(5);
}
}
abstract class Bumo{
public final void display() { System.out.println("나는 부모의 메소드"); } //메소드를 final로 만들면 자식메소드는 오버라이드할 수없다.
}
class Jasik extends Bumo{
/*@Override
public void display() { System.out.println("나는 부모의 메소드"); }*/
public void display(int su) { System.out.println("나는 자식의 메소드"); } //부모 display method가 final로 해주어서 int su를 추가하여 오버로딩으로 바꿔줌.
}
출력:
나는 부모의 메소드
나는 자식의 메소드
--------------------------ㅡㅡㅡㅡㅡㅡㅡㅡㅡ
public class FinalDemo2 {
public static void main(String[] args) {
Parent p = new Child();
p.display(); //자식의 메소드
p.print(); //부모의 메소드
}
}
class Parent{
public void display() { System.out.println("Called display()");}
public final void print() { System.out.println("Called print()");}
}
class Child extends Parent{
@Override
public void display() { System.out.println("Child's Called display()"); }
}
출력:
Child's Called display()
Called print()
//만약 class Parent를 -> final class Parent로 바꿔주면 자식을 가질 수없다.
//final class와 abstract class는 상극. abstract class는 자식을 낳아야만하는 class이고, final class 는 자식을 못낳는 class.
//그래서 final class 와 abstract class 는 동시에 사용이 불가능하다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Deprecation
public class DeprecationDemo {
public static void main(String[] args) {
java.util.Date now = new java.util.Date();
int year = now.getYear();
System.out.println("year = " + year);
}
}
//getYear부분이 중간이 줄이 그어져 있고 warning이 뜬것을 볼 수있다.
위코드를 터미널에서 컴파일하면 javac DeprecationDemo.java 를 쓰면 warning이 든다. 이유를 알아보면 -Xlint를 써도되지만
javac -deprecation DeprecationDemo.java를 쓰면 getYear 떄문인 것을 알 수 있다.
API에서 보면 Calendar.get(Calendar.YEAR) - 1900 이렇게 나왔는데, 이는 저렇게 쓰고 1900을 빼면 원래나오는 수가 나온다고 의미.
---------------------
import java.awt.Color;
import java.awt.Frame;
public class DeprecationDemo1 {
private Frame f;
private void display(){
f = new Frame("Frame Demo");
f.setSize(400,300);
f.setBackground(Color.YELLOW);
f.show();
}
public static void main(String[] args) {
new DeprecationDemo1().display();
}
}
//여기서 show부분이 위코드의 getYear과 같이 글자 중간에 줄이 그어져 있고 warning이 뜬 것을 볼 수있다.
출력: 노랑색창이 하나뜸. 닫혀지지않음. 종료 이벤트를 안만들어줘서..
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
/*
* Nested Class --> static class
* 1. 생성방법: Outer class 의 이름으로 생성(outer class의 주소 불필요)
* 2. 사용목적:
* 3. 제한사항: Outer class의 멤버변수와 멤버메스드 접근 안됨.
*/
public class NestedClassDemo {
public static void main(String[] args) {
Outer.Inner in = new Outer.Inner();
in.display();
}
}
class Outer{
private int a = 5;
private static int b = 10;
public static void print() { System.out.println("print()"); }
public void show() { System.out.println("show()"); }
public Outer(){}
protected static class Inner{
private static int c = 15;
private int d = 20;
public Inner(){ System.out.println("성공"); }
public void display(){
System.out.println("d = " + d); //a접근안됨(에러), b c d 됨
print(); //show() 접근안됨
}
}
}
//멤버는 static에게 접근 가능하다. static은 바깥쪽 멤버에 접근이 불가능하다. 주소를 사용해야 가능.
------------------
public class NestedClassDemo {
public static void main(String[] args) {
A.B.C.D d = new A.B.C.D();
}
}
class A{
static class B{
static class C{
static class D{
public D() { System.out.println("success"); }
}
}
}
}
//static 메소드를 만드는 목적은 주소없이 접근하기 위해서이다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
/*
* Member Class
* 1. 생성방법 : Outer class의 주소로 접근
* 2. 사용목적 : 다중상속
* 3. 제한사항 : static variable 과 static method를 소유할 수없다.
*/
public class MemberClassDemo {
public static void main(String[] args) {
Outer1 out = new Outer1();
Outer1.Inner1 in = out.new Inner1();
in.display();
}
}
class Outer1{
private int a = 5; //outer class's member variable
private static int b = 10; //outer class's static variable
class Inner1{
private int c = 50;
private static int d = 100; //에러발생. 멤버클래스는 static 변수와 static 메소드를 가질 수 없다.
public Inner1(){ System.out.println("Success"); }
public void display(){
System.out.println("d = " + d); //a,b,c 가능, d 에러발생.
}
}
}
--------------------
public class MemberClassDemo {
public static void main(String[] args) {
CC cc = new CC();
CC.DD dd = cc.new DD();
dd.display();
}
}
class AA{int a = 5;}
class BB{int b = 10;}
class CC extends AA{
int c = 100;
class DD extends BB{
int d = 5000;
public void display(){
System.out.printf("a = %d, b = %d, c = %d, d = %d\n", a,b,c,d);
}
}
}
출력:
a = 5, b = 10, c = 100, d = 5000
Member Inner Class는 스태틱만 안가지면 된다. 그럼 모든것을 다할 수 있다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
/*
* Local Class
* 1. 생성방법 : Inner class가 속해 있는 메소드가 호출돼야 한다.
* 2. 사용목적 : 객체의 life cycle 을 짧게...
* 3. 제한사항 : 1) access modifier 사용 불가능
* 2) static 사용불가능
* 3) local Inner class가 속해있는 메소드의 지역변수 접근 불가능.
* 4) local inner class가 속해있는 메소드의 지역상수 접근 가능.
*/
public class LocalClassDemo {
public static void main(String[] args) {
Outer2 out = new Outer2();
out.display();
}
}
class Outer2{
private int a = 5;
private static int b = 10;
public void display(){ //Outer class's method
int c = 100; //local variable -지역변수는 public, private 등을 못 붙인다. static 못붙인다.
class Inner2{ // 따라서 지역클래스도 access modifier을 붙일 수 없다. static 못붙인다.
int d = 500;
public Inner2(){ System.out.println("Success"); }
public void print(){
System.out.println("d = " + d); //a,b,d 가능. c 에러발생. 지역클래스는 지역변수에 접근 불가능. d는 자기것이기 때문에 접근가능.
} //만약 c가 final int c 라면 접근 가능.
}
Inner2 in = new Inner2(); //메소드에서는 순서를 지켜줘야한다. class Inner2와 이것이 순서가 바뀌면 에러발생.
in.print();
}
}
//local class는 일반적으로 잘사용하지 않으나 이벤트에 사용.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
4. Anonymous Class
public class AnonymousClassDemo {
public static void main(String[] args) {
new AnonymousClassDemo().print();
}
void print(){
final int finalNum = 10;
/*Temp t = new Temp();
t.display();*/ //일반적으로 이와같이 시작하는 것이 아니라, 아래처럼
Temp t= new Temp(){ //지역클래스이기떄문에 private public 못붙인다. static 못붙인다.
@Override
public void display(){
System.out.println("재정의된 display()");
System.out.println("finalNum = " + finalNum); //final 상수는 접근가능
}
}; //<-- 이 세미콜론은 지우면안된다. 지우면 에러발생.
t.display();
}
}
class Temp{
public void display(){
System.out.println("Called display()");
}
}
//local class와 제한사항이 거의 똑같지만 하나더 추가 된것이 세미콜론이다.
출력:
재정의된 display()
finalNum = 10
================================================================
enum
Class A, interface AA, enum AAA는 표현한 것이 같다
enum은 나열의 목적이지, 값의 저장이나 연산을 하진않는다.
Class A {
public static final int SUN = 0;
public static final int MON = 0;
}
interface AA{
int SUN = 0, MON = 1;
}
enum AAA{
SUN, MON;
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
값은 줄 수 있지만 생성자를 통해 줘야한다.
enum 내에서는 순서가있다.
생성자의 앞에 아무것도 붙이지 못한다.
public enum Weekend {
SUN(0), MON(5), TUE(100), WED(250), THU(500), FRI(1000), SAT(2000); //값을 주려면 모두 다주어야한다.
private int value;
Weekend(int value){ //생성자 앞에 아무것도 붙이면 안된다.
this.value = value;
}
public int getValue() { return this.value; }
}
public class EnumDemo {
public static void main(String[] args) {
Weekend w = Weekend.WED;
//int su = (int)w; //자바에서는 enum에 들어있는 값들을 숫자로 바꿀 수없다.
System.out.println(w);
System.out.println(w.toString());
System.out.println(w.ordinal()); //c에서처럼 숫자로
Weekend [] array = Weekend.values();
for(int i = 0 ; i < array.length ; i++){
System.out.printf("%s(%d) --> %d\n", array[i].name(), array[i].getValue(), array[i].ordinal());
}
}
}
//enum은 switch 를 사용하는데 유용. 데이터에대한 binary를 지정하고자할때 유용.
//enum은 switch 를 사용하는데 유용. 데이터에대한 binary를 지정하고자할때 유용.
출력:
WED
WED
3
SUN(0) --> 0
MON(5) --> 1
TUE(100) --> 2
WED(250) --> 3
THU(500) --> 4
FRI(1000) --> 5
SAT(2000) --> 6
Weekend [] array = Weekend.values();
for (Weekend we : array){
System.out.println(we.name() +"(" + we.getValue() + ") --> " +we.ordinal());
이렇게 써줘도 똑같이 값이 출력된다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Exception
exception 은 개발자입장에서 자기가 생각한 상황에서 벗어난 상황을 생각해서 처리하는 것.
import java.util.Scanner;
public class ExceptionDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int su, num;
System.out.print("첫번째 숫자 입력 :");
su = scan.nextInt();
System.out.print("두번째 숫자 입력(0은 안됨) :");
num = scan.nextInt(); //두번째 숫자가 0을 받으면 오류가 발생한다.
try{
System.out.printf("%d / %d = %d\n", su, num, (su/num));
}catch (ArithmeticException ex){
System.out.println("예외상황발생");
}
}
}
출력:
첫번째 숫자 입력 :3
두번째 숫자 입력 :0
예외상황발생
----------------------
checked exception :try, catch를 꼭 써야한다.
unchecked exception : error와 runtimeException의 자식들은 꼭 써주지 않아도된다.
위 코드에서 사용자가 조심하면 try catch는 써주지 않아도된다.
checked exception은 try catch를 써주지 않으면 컴파일단계에서 에러가난다
import javax.swing.JOptionPane;
public class ExceptionDemo1 {
public static void main(String[] args) {
int kor = Integer.parseInt(JOptionPane.showInputDialog("국어점수를 입력하세요 : "));
System.out.printf("kor = %d\n", kor);
}
}
//여기서 예외상황은, 만약 점수를 aaa를 입력했다면??
//이 코드는 실행중에 오류를 발생시킬 수 있으므로 runtimeException이라고 한다.
//Integer/parseInt는 부모가 java.lang.RuntimeException이다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
가장많이 발생하는 exception
public class ExceptionDemo2 {
public static void main(String[] args) {
Test t = new Test();
t.su = 10;
System.out.println(t.su);
t = null;
System.out.println(t.su);
}
}
class Test{
int su;
}
출력:
10
Exception in thread "main" java.lang.NullPointerException
at ExceptionDemo2.main(ExceptionDemo2.java:8)
exception 중 널포인터익셉션이 80프로정도발생한다. 이 코드에서는 Test t를 널값을 넣어주었는데 t.su를 출력하려고 해서 나타난 에러.
널포인터익셉션 에러는 얻어오려는 값이 비어있을때 발생한다.
또 다른 경우를 보면
public class ExceptionDemo2 {
public static void main(String[] args) {
int su = -5;
int [] array = new int[su];
}
}
class Test{
int su;
}
이런 Exception in thread "main" java.lang.NegativeArraySizeException
at ExceptionDemo2.main(ExceptionDemo2.java:10)
에러가 발생한다.
여기서
try{
int [] array = new int[su];
}catch(NegativeArraySizeException ex){
System.out.println("예외상황발생");
}
이렇게 처리를 해주면 정상적으로 돌아갈 것이다. 하지만 catch부분을
catch (ArithmeticException ex){
System.out.println("예외상황발생");
}
다른 예외상황을 써준다면 다시 오류가 발생할 것이다.
------
만약 아래코드에서 1번 줄에서 예외상황이 발생한다면 aaaaa는 출력하지 않고 catch로 간다.
try{
1번-> System.out.printf("%d / %d = %d\n", su, num, (su/num));
System.out.println("aaaaa");
}catch (ArithmeticException ex){
System.out.println("예외상황발생");
}
-----------------------
try{
System.out.printf("%d / %d = %d\n", su, num, (su/num));
}catch (ArithmeticException ex){
System.out.println("예외상황발생");
}catch (NullPointerException ex){
System.out.println("NullPointerException");
}catch(ArrayIndexOutOfBoundsException ex){
System.out.println("ArrayIndexOutOfBoundsException");
}
어떤 exception인지 몰라서 이렇게 써주는 것은 괜찮다. 하지만 만개의 exception이 있다면 모두 이렇게 써주기는 힘들것이다.
catch(Exception ex){
System.out.println("마지막 보루");
}
그래서 부모를 써주는 방법이 있다.
----------------------
만일 아래와 같이 써주면 Exception 의 아래에 있는 예외처리상황은 쓸데 없는 처리가 된다.
try{
System.out.printf("%d / %d = %d\n", su, num, (su/num));
}catch (Exeption ex){
System.out.println("예외상황발생");
}catch (NullPointerException ex){
System.out.println("NullPointerException");
}
그래서 위로 갈수록 자식(더좁은폭)으로 가야한다.
물론
try{
System.out.printf("%d / %d = %d\n", su, num, (su/num));
}catch (Exeption ex){
System.out.println("예외상황발생");
}
이렇게만 써줘도 되긴하지만 그러면 어떤 예외상황인지 알수 없게 된다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Throwing Exceptions
public class ExceptionDemo3 {
public static void main(String[] args) {
ExceptionDemo3 ed = new ExceptionDemo3();
ed.a();
}
void a(){
b();
}
void b(){
c();
}
void c(){
d();
}
void d(){
System.out.println(5/0);
}
}
출력:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ExceptionDemo3.d(ExceptionDemo3.java:17)
at ExceptionDemo3.c(ExceptionDemo3.java:14)
at ExceptionDemo3.b(ExceptionDemo3.java:11)
at ExceptionDemo3.a(ExceptionDemo3.java:8)
at ExceptionDemo3.main(ExceptionDemo3.java:5)
경로상의 거치는 모든 메소드는 다걸린다. d()에서 해결 못하면 c()로 계속해서 넘겨준다.
그러면 d에서 발생한 에러지만 중간인 b 메소드를 try catch 처리 해주면
void b(){
try{
c();
}catch(Exception ex) {System.out.println("여기서 잡았음"); }
}
중간에 커트되어 더이상 오류가 발생하지 않는다.
이것이 exception의 장점이다. 전파되기 때문에 누구라도 중간에 잡아주기만 하면 더이상 에러가 발생하지 않는다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Exceptions에 대한 정보를 출력하는 방법
import javax.swing.JOptionPane;
import java.util.Scanner;
public class ExceptionDemo4 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ExceptionDemo4 ed = new ExceptionDemo4();
try{
ed.input(scan);
}catch (RuntimeException ex){
JOptionPane.showMessageDialog(null,ex.getMessage());
//System.out.println(ex); //1. ex.getMessage() : 사용자용 2. ex.toString
//3.ex.printStackTrace(); //일련의 과정을 추적해서 찍는.. 개발자용
}
}
void input(Scanner scan) {
System.out.println("국어 점수 입력 : ");
int kor = scan.nextInt();
if(kor < 0 || kor > 100)
throw new RuntimeException("국어 점수는 0부터 100점까지 입니다");
}
}
//이 코드는 범위에벗어나는 점수를 입력했을 때 "국어점수는 0부터 100점까지 입니다" 의 메세지를 띄어준다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Declaring Exceptions
위 소스에서 input을
void input(Scanner scan) throws RuntimeException { //만드는 사람은 반드시 exception을 던지고 있는 것을 선언해준다. 가져다 쓰는 사람을 위해서.
System.out.println("국어 점수 입력 : ");
int kor = scan.nextInt();
if(kor < 0 || kor > 100)
throw new RuntimeException("국어 점수는 0부터 100점까지 입니다");
}
이렇게 써준다. 메소드 안에서는 throw, 밖에서는 throws 이다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
import java.io.File; //ctrl+shift+o
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JFileChooser;
public class ExceptionDemo5 {
public static void main(String[] args) throws FileNotFoundException { //input에서 던진 것을 여기서 ed.input을 try catch처리 해주거나 throws를 해주어야한다. 컴파일러에게 던진다.
ExceptionDemo5 ed = new ExceptionDemo5();
ed.input();
}
void input() throws FileNotFoundException{ //throws FileNotFoundException를 써주거나 try catch 처리를 해주어야 한다.
File file = null;
JFileChooser jc = new JFileChooser();
int result = jc.showOpenDialog(null);
if(result == JFileChooser.APPROVE_OPTION){ //열기버튼을 눌렀다면
file = jc.getSelectedFile();
}
Scanner scan = new Scanner(file);
for(int i = 0 ; i <12 ; i++){
System.out.println(scan.nextLine());
}
}
}
//showOpenDialog로 파일을 선택할 수 있게 창이 뜬다. 그래서 열려는 파일을 찾아서 선택한다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
finally - exception의 발생여부와 관계없이 무조건 실행된다.
위 코드를 throws FileNotFoundException을 써주지 말고 try catch처리를 해주자.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JFileChooser;
public class ExceptionDemo5 {
public static void main(String[] args) {
ExceptionDemo5 ed = new ExceptionDemo5();
ed.input();
}
void input() {
File file = null;
JFileChooser jc = new JFileChooser();
int result = jc.showOpenDialog(null);
if(result == JFileChooser.APPROVE_OPTION){ //열기버튼을 눌렀다면
file = jc.getSelectedFile();
}
Scanner scan = null;
try{
scan = new Scanner(file);
for(int i = 0 ; i <12 ; i++){
System.out.println(scan.nextLine());
}
}catch(FileNotFoundException ex){
System.out.println("File Not Found");
}finally{
System.out.println("항상처리");
scan.close();
}
}
}
순서는 try - catch - finally 가 정식이다. 그리고 try - catch 만 쓸 수 있다.
catch를 쓰지않고 throws FileNotFoundException 을 하고 try - finally 도 가능하다.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Creating Your Own Exception - 필요하다면 내가 직접 exception을 만들 수 있다.
이것을 명심해야한다. 1. 생성자를 반드시 써야한다. 2. 부모가 누구냐를 따져야한다.
runtime exception을 부모로한다면 unchecked exception이 될 것이고~~.
//unchecked exception
public class EnglishException extends RuntimeException{
public EnglishException (String msg){
super(msg); //나의 부모가 처리
}
}
//checked Exception
public class KoreanException extends Exception {
public KoreanException (String msg){
super(msg);
}
}
//국어는 checked, 영어는 unchecked
public class Student {
private int kor, eng;
public Student(int kor, int eng) throws KoreanException, EnglishException {
if(kor < 0 || kor > 100) throw new KoreanException("국어점수는 0부터 100점까지입니다.");
else this.kor = kor;
if(eng < 0 || eng > 100) throw new EnglishException("영어점수는 0부터 100점까지입니다.");
else this.eng = eng;
}
@Override
public String toString(){
return String.format("kor = %d, eng = %d" , this.kor, this.eng);
}
}
import java.util.Scanner;
import javax.swing.JOptionPane;
public class ExceptionDemo6 {
public static void main(String[] args) {
ExceptionDemo6 ed = new ExceptionDemo6();
ed.input();
}
void input(){
int kor, eng;
Scanner scan = new Scanner(System.in);
System.out.print("국어점수 : "); kor = scan.nextInt();
System.out.print("영어점수 : "); eng = scan.nextInt();
Student chulsu = null; //try를 써주지 않으면 KoreanException은 checked exception이기 떄문에 오류 발생.
try{
chulsu = new Student(kor, eng);
System.out.println(chulsu);
}catch(KoreanException ex){
JOptionPane.showMessageDialog(null, ex.getMessage());
}catch(EnglishException ex){
JOptionPane.showMessageDialog(null, ex.getMessage());
}catch(Exception ex){
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
}