인터페이스
package sec04.exam01;
public interface Vehicle {
public void run();
}
구현
package sec04.exam01;
public class Anonymous {
Vehicle field = new Vehicle() {
@Override
public void run() {
System.out.println("필드 초기값 ");
}
};
void method() {
Vehicle localVar = new Vehicle() {
@Override
public void run() {
System.out.println("로컬 변수값 대입");
}
};
localVar.run();
}
void method2(Vehicle v) {
v.run();
}
}
실행
package sec04.exam01;
public class AnonyEx {
public static void main(String[] args) {
Anonymous anony = new Anonymous();
anony.field.run();
anony.method();
anony.method2(new Vehicle() {
@Override
public void run() {
System.out.println("매개값");
}
});
}
}
<결과>
필드 초기값
로컬 변수값 대입
매개값
중첩 인터페이스 타입 필드 선언
중첩 인터페이스 선언
package sec04.exam02;
public class CheckBox {
static interface OnSelectListener {
void onSelect();
}
OnSelectListener listener;
void setOnSelectListener(OnSelectListener listener) {
this.listener = listener;
}
void selct() {
listener.onSelect();
}
}
실행
package sec04.exam02;
public class CheckBoxEx {
public static void main(String[] args) {
CheckBox checkBox = new CheckBox();
checkBox.setOnSelectListener(new CheckBox.OnSelectListener() {
@Override
public void onSelect() {
System.out.println("배경을 변경 합니다.");
}
});
checkBox.selct();
}
}
<결과>
배경을 변경 합니다.
예외 클래스
예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
자바는 예외가 발생할 가능성이 높은 코드를 컴파일할 때 예외 처리 유무를 확인한다.
하지만 모든 예외에 대해서 예외 처리 유무를 확인하는 것은 아니다.
예외와 예외 클래스
예외는 두 가지 종류가 있다. 하나는 일반 예외이고, 다른 하나는 실행 예외 이다.
- 일반 예외 : 컴파일러 체크 예외라고도 하는데, 컴파일러가 강제로 예외처리 요구하는 것
- 실행 예외 : 컴파일러 넌 체크 예외라고도 하는데, 컴파일러가 예외 처ㅣ를 강제하지 않는 것
일반 예외와 실행 예외 클래스는 RuntimeException 클래스 기준으로 구별 한다.
클래스 상속 관계에서 부모(조상)에 RuntimeException이 있다면 실행 예외 클래스이다.
NullPointerException
자바 프로그램에서 강자 빈번하게 발생하는 실행 예외, 이것은 객체 참조가 없는 상태, 즉 nill값을 갖는 참조
변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생, 객체가 없는 상태에서 객체를 사용하려 했으니 예외 발생
package sec01.exam01;
public class NullEx {
//실행 예외
public static void main(String[] args) {
// 컴파일러가 오류 잡음
// String data = null;
// System.out.println(data.toString());
//NullPointerException 예외 발생
String data2 = null;
System.out.println(data2.toString());
//NullPointerException 예외 발생
// 값이 null인지 비교
String data3 = null;
if(data3 != null) {
System.out.println(data3.toString());
}else {
System.out.println("값이 null이 아님");
}
//NullPointerException 예외 발생
}
}
ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과할 경우 발생하는 실행 예외
예를 들어 길이가 3인 int[]arr = new int[3] 배열을 선언했다면, 배열 항목을 지정하기 위해 arr[0]~arr[2]를
사용할 수 있다. 하지만 arr[3]을 사용하면 인덱스 범위를 초과했기 때문에 해당 예외 발생
실행 매개값 넣어주는 방법
이클립스
Run => Run Configurations => Arguments => Program arguments => 입력
명령 프롬프트
java -p . -m chap10/sec01.exam01.ArrayEx 가나다
package sec01.exam01;
public class ArrayEx {
public static void main(String[] args) {
//ArrayIndexOutOfBoundsException 에러
if(args.length != 2) {
System.out.println("매개 값이 부족 합니다.");
System.exit(0);
}
String data = args[0];
String data1 = args[1];
System.out.println(args.length);
System.out.println("args[0] : " + data);
System.out.println("args[1] : " + data1);
}
}
배열 길이를 먼저 조사하는게 좋은 코드
NumberFormatException
프로그램을 개발하다 보면 문자열로 되어 있는 데이터를 숫자로 변경하는 경우가 자주 발생한다.
문자열을 숫자로 변환하는 방법은 여러 가지 있지만 주로 다음 코드를 가장 많이 사용한다.
package sec01.exam01;
public class NumberFormatEx {
public static void main(String[] args) {
// int로 변경 가능
String data1 = "100";
int var1 = Integer.parseInt(data1);
System.out.println(var1);
// 에러 int로 변경 불가
String data2 = "100as";
int var2 = Integer.parseInt(data2);
System.out.println(var1);
// NumberFormatException 예외 발생
}
}
ClassCastException
타입 변환은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생한다.
이러한 관계가 아니라면 클래스는 다른 타입으로 변환할 수 없기 때문에 해당 에러가 발생
package sec01.exam02;
class Animal{} // 부모
class Dog extends Animal{}// 자식
class Cat extends Animal{}// 자식
public class ClassCastEx {
//매개변수가 부모타입
public static void changeDog(Animal animal) {
// Dog dog = (Dog) animal; // 강제 형변환
if(animal instanceof Dog) {
Dog dog = (Dog) animal;
}else {
System.out.println("안됩니다.");
}
}
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
// 가능
changeDog(dog);
//ClassCastException 에러
// changeDog(cat);
}
}
예외 처리
자바 컴파일러는 소스 파일을 컴파일할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면 컴파일
에러를 발생시켜 개발자가 강제적으로 예외 처리 코드를 작성하도록 요구합니다. 그러나 실행 예외는
컴파일러가 체크해주지 않기 때문에 개발자의 경험을 바탕으로 예외 처리 코드를 작성해야 한다.
예외 처리 코드
try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할
경우 예외 처리를 할 수 있도록 해준다.
finally 블록은 생략 가능, 예외 발생 여부와 상관없이 항상 실행할 내용이 있을 경우에만 작성
일반 예외 처리
일반 예외 처리
package sec01.exam03;
public class TryEx {
//try, catch 예외 처리 코드 basic
public static void main(String[] args) {
try {
Class.forName("java.leng.String2");// 해당 파일 존재하지 않음
} catch (ClassNotFoundException e) { // <= 해당 위치에 오류코드 넣기
e.printStackTrace();// 오류 코드 확인
System.out.println("클래스가 존재하지 않습니다.");
//System.out.println(e.getMessage());
// TODO Auto-generated catch block
// e.printStackTrace();
}
}
}
실행 예외 처리
다중 catch
package sec01.exam03;
public class TryCatchFinallyRuntimeEx {
// 다중 catch
public static void main(String[] args) {
String data1 = null;
String data2 = null;
try {
data1 = args[0];
data2 = args[1];
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(value1 + "+" + value2 + "=" + result);
} catch (ArrayIndexOutOfBoundsException e) {// <= 배열 예외 생겼을때 처리
System.out.println("실행 매개값의 수가 부족합니다.");
} catch (NumberFormatException e) {// <= 문자열로 되어 있는 데이터를 숫자로 변경할때 예외 처리
e.printStackTrace();
System.out.println("숫자로 변화할 수 없습니다.");
}finally {// <= 항상 실행
System.out.println("다시 실행 하세요.");
}
}
}
선언
package sec03.exam01;
public class Car {
class Tire {}
static class Engine{}
}
실행
package sec03.exam01;
public class NestedEx {
public static void main(String[] args) {
Car myCar = new Car();
// 인스턴스 멤버 클래스
Car.Tire tire = myCar.new Tire();
// 정적 멤버 클래스
Car.Engine engine = new Car.Engine();
}
}
중첩 인터페이스 타입 필드 선언 예제
선언
package sec03.exam02;
public class CheckBox {
static interface OnselectListener {
void onSelect();
}
OnselectListener listener;
public void setListener(OnselectListener listener) {
this.listener = listener;
}
void select() {
listener.onSelect();
}
}
구현 객체
package sec03.exam02;
import sec03.exam02.CheckBox.OnselectListener;
public class BackgroundChangeListener implements OnselectListener {
@Override
public void onSelect() {
System.out.println("배경을 변경합니다.");
}
}
실행
package sec03.exam02;
public class CheckEX {
public static void main(String[] args) {
CheckBox checkBox = new CheckBox();
checkBox.setListener(new BackgroundChangeListener());
checkBox.select();
}
}
<결과>
package sec03.exam02;
public class CheckEX {
public static void main(String[] args) {
CheckBox checkBox = new CheckBox();
checkBox.setListener(new BackgroundChangeListener());
checkBox.select();
}
}
익명 자식 객체 생성
상속
package sec03.exam03;
// 익명 구현 객체
public class Parent {
void parentMethod() {}
}
class Child extends Parent{}
선언
package sec03.exam03;
// 익명 구현 객체
public class A {
Parent field = new Parent() {
int childField;
void childMethod() {}
@Override
void parentMethod() {
}
};
void method3() {
field.parentMethod();
}
void method2(Parent parent) {}
void method() {
method2(new Parent() {
int childField;
void childMethod() {}
@Override
void parentMethod() {
}
});
Parent localVer = new Child() {
int childField;
void childMethod() {}
@Override
void parentMethod() {
}
};
};
}
익명 자식 객체 생성 2
부모 클래스
package sec03.exam04;
public class Person {
void wake() {
System.out.println("7시에 기상");
}
}
익명 자식 객체 생성
package sec03.exam04;
public class Anonymous {
//필드
Person field = new Person() {
// 익명의 객체 내부에서만 가능
void work() {
System.out.println("출근합니다.");
}
// 부모메서드 재정의 외부에서도 가능
@Override
void wake() {
System.out.println("6시에 기상");
work();// 내부 메서드 호출
}
};
void method1() {
// 지역변수
Person localVar = new Person() {
// 익명의 객체 내부에서만 가능
void work() {
System.out.println("출근합니다.");
}
// 부모메서드 재정의 외부에서도 가능
@Override
void wake() {
System.out.println("6시에 기상");
work();// 내부 메서드 호출
}
};
}
void method2(Person person) {
person.wake();
}
}
익명 자식 객체 실행
package sec03.exam04;
public class AnonyEx {
public static void main(String[] args) {
Anonymous anony = new Anonymous();
// anony.field.wake();
// anony.method1();
anony.method2(new Person() {
// 익명의 객체 내부에서만 가능
void work() {
System.out.println("출근합니다.");
}
// 부모메서드 재정의 외부에서도 가능
@Override
void wake() {
System.out.println("6시에 기상");
work();// 내부 메서드 호출
}
});
}
}
<결과>
6시에 기상
출근합니다.