[혼공자바] 6주차: 예외와 API 클래스
본문 바로가기

혼공 스터디/혼자 공부하는 자바

[혼공자바] 6주차: 예외와 API 클래스

728x90
반응형

Chap 10 예외처리

1. 예외 클래스

  • 자바에서는 컴퓨터 하드웨어 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것을 에러(error)라고 함
  • 에러 이외에 프로그램 자체에서 발생하는 오류는 예외(exception)라고 함.

 

  • 예외(exception)란 사용자의 잘못된 조작 도는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
  • 예외가 발생하면 프로그램이 곧바로 종료된다는 점에서 에러와 비슷
  • 그러나 예외는 예외처리(exception handling)를 통해
    프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있음
  • 자바는 예외가 발생할 가능성이 높은 코드를 컴파일할 때 예외 처리 유무를 확인한다
  • 만약 예외 처리 코드가 없다면 컴파일 되지 않는다.
  • 하지만 모든 예외에 대해서 예외 처리 유무를 확인하는 것은 아니다
  •  

1) 예외와 예외 클래스

  • 일반 예외(exception)
    • 컴파일러 체크 예외라고도 함
    • 프로그램 실행 시 예외가 발생한 가능성이 높기 때문에 자바 소스를 컴파일하는 과정에서
      해당 예외 처리 코드가 있는지 검사한다
    • 만약 예외 처리 코드가 없다면 컴파일 오류가 발생
  • 실행 예외(runtime exception)
    • 컴파일러 넌 체크 예외
    • 실행 시 예측할 수 없이 갑자기 발생하기 때문에
      컴파일하는 과정에서 예외 처리 코드가 있는지 검사하지 않는다
  • 자바에서는 예외를 클래스로 관리한다.
  • JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다.
  • 그리고 나서 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해줌
  • 모든 예외 클래스는 다음과 같이 java.lang.Exception 클래스를 상속 받는다.

  • 일반 예외와 실행 예외 클래스는 RuntimeException 클래스를 기준으로 구별
  • RuntimeException의 하위 클래스가 아니면 일반 예외 클래스
  • RuntimeException의 하위 클래스이면 실행 예외 클래스
  • 클래스 상속 관계에서 부모에 RuntimeException이 있다면 실행 예외 클래스

 

2) 실행 예외

  • 실행 예외는 자바 컴파일러가 체크하지 않기 때문에 오로지 개발자의 경험에 의해서 
    예외 처리 코드를 작성해야 함
  • 만약 개발자가 실행 예외에 대해 예외 처리 코드를 넣지 않았을 때,
    해당 예외가 발생하면 프로그램은 곧바로 종료됨.

 

(1) NullPointerException

  • 자바 프로그램에서 가장 빈번하게 발생하는 실행 예외는 java.lang.NullPointerException이다.
  • 객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생
  • 객체가 없는 상태에서 객체를 사용하려 했으니 예외가 발생하는 것
NullPointerException
package sec01.exam01;


public class NullPointerExceptionExample {
public static void main(String[] args) {
String data = null;
System.out.println(data.toString());
}
}
Exception in thread "main" java.lang.NullPointerException
        at chap10/sec01.exam01.NullPointerExceptionExample.main(NullPointerExceptionExample.java:6)
  • data 변수는 null 값을 가지고 있기 때문에 String 객체를 참조하고 있지 않다.
  • 하지만 String 객체의 toString() 메소드를 호출하고 있음
  • 여기서 NullPointerException이 발생
  • 프로그램에서 예외가 발생하면 예외 메시지가 Console 뷰에 출력되면서 프로그램이 종료됨
  • Console 뷰에 출력되는 내용에는 어떤 예외가 어떤 소스의 몇 번째 코드에서 발생했는지에 대한 
    정보가 들어 있다.
  • 앞 예제의 경우 NullPointerExceptionExample.java 소스의 6번째 코드에 발생했음을 알 수 있음.
  • Console 뷰에서 밑줄 처리에 NullPointerExceptionExample.java:6을 마우스로 클릭하면
    소스 편집기는 정확히 NullPointerExceptionExample.java의 6라인을 하이라이팅해줌

 

 

(2) ArrayIndexOutOfBoundsException

  • 배열에서 인덱스 범위를 초과할 경우 실행 예외인 java.lang.ArrayIndexOutOfBoundsException이 발생
  • 길이가 3인 int[] arr = new int[3] 배열을 선언했다면,
    배열 항목을 지정하기 위해 arr[0] ~ arr[2]를 사용할 수 있습니다.
ArrayIndexOutOfBoudsException
package sec01.exam02;


public class ArrayIndexOutOfBoundsExceptionExample {
public static void main(String[] args) {
String data1 = args[0];
String data2 = args[1];

System.out.println("args[0]: " + data1);
System.out.println("args[1]: " + data2);
}
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at chap10/sec01.exam02.ArrayIndexOutOfBoundsExceptionExample.main(ArrayIndexOutOfBoundsExceptionExample.java:5)
ArrayIndexOutOfBoundsException
package sec01.exam03;

public class ArrayIndexOutOfBoundsExceptionExample {
public static void main(String[] args) {
if(args.length == 2) {
String data1 = args[0];
String data2 = args[1];
System.out.println("args[0]: " + data1);
System.out.println("args[1]: " + data2);
} else {
System.out.println("두 개의 실행 매개값이 필요합니다.");
}
}
}
두 개의 실행 매개값이 필요합니다.

 

(3) NumberFormatException

  • 프로그램을 개발하다 보면 문자열로 되어 있는 데이터를 숫자로 변경하는 경우 자주 발생
  • 문자열을 숫자로 변환하는 방법은 여러 가지가 있지만 주로 다음 코드를 가장 많이 사용

NumberFormatException
package sec01.exam04;


public class NumberFormatExceptionExample {
public static void main(String[] args) {
String data1 = "100";
String data2 = "a100";

int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);

int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
}
}
Exception in thread "main" java.lang.NumberFormatException: For input string: "a100"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:661)
at java.base/java.lang.Integer.parseInt(Integer.java:777)
at chap10/sec01.exam04.NumberFormatExceptionExample.main(NumberFormatExceptionExample.java:9)

 

 

(3) ClassCastException

  • 타입 변환(Casting)은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생
  • 이런 관계가 아니라면 클래스는 다른 타입으로 반환할 수 없기 때문에 ClassCastException이 발생

  • 위와 같은 상속 관계와 구현 관계가 있다고 가정하자.
  • Animal 타입 변수에 대입된 객체가 Dog이므로 다시 Dog 타입으로 변환하는 것은 아무런 문제가 없음
  • 마찬가지로 RemoteControl 타입 변수에 대입된 객체가 Television이므로 
    다시 Television 타입으로 변환하는 것도 아무런 문제가 없다.
Animal animal = new Dog();
Dog dog = (Dog) animal;
RemoteControl rc = new Television();
Television tv = (Television) rc;
  • 그러나 다음과 같이 타입 변환을 하면 ClassCastException이 발생
  • 대입된 객체가 아닌 다른 클래스 타입으로 타입 변환했기 때문
Animal animal = new Dog();
Cat cat = (Cat) animal;
RemoteControl rc = new Television();
Audio audio = (Audio) rc;
  • ClassCastException을 발생시키지 않으려면 타입 변환 전에 변환이 가능한지 instanceof 연산자로 확인
  • instanceof 연산의 결과가 true이면 좌항 객체를 우항 타입으로 변환이 가능
Animal animal = new Dog() ;
if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
} else if (animal instanceof Cat) {
    Cat cat = (Cat) animal;
}
Remocon rc = new Audio() ;
if (rc instanceof Television) {
    Television tv = (Television) rc;
} else if (rc instanceof Audio) {
    Audio audio = (Audio) rc;
}
ClassCastException
package sec01.exam05;


public class ClassCastExceptionExample {
public static void main(String[] args) {
Dog dog = new Dog();
changeDog(dog);

Cat cat = new Cat();
changeDog(cat);
}

public static void changeDog(Animal animal) {
//if(animal instanceof Dog) {
Dog dog = (Dog) animal; //ClassCastException �߻� ����
//}
}
}


class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
Exception in thread "main" java.lang.ClassCastException: class sec01.exam05.Cat cannot be cast to class sec01.exam05.Dog (sec01.exam05.Cat and sec01.exam05.Dog are in module chap10 of loader 'app')
at chap10/sec01.exam05.ClassCastExceptionExample.changeDog(ClassCastExceptionExample.java:14)
at chap10/sec01.exam05.ClassCastExceptionExample.main(ClassCastExceptionExample.java:9)

 

 

 

 

2. 예외 처리

  • 자바 컴파일러는 소스 파일을 컴파일할 때 일반 예외가 발생할 가능성이 있는 코드를 발견하면
    컴파일 에러를 발생시켜 개발자가 강제적으로 예외 처리 코드를 작성하도록 요구한다.
  • 그러나 실행 예외는 컴파일러가 체크해주지 않기 때문에 개발자의 경험을 바탕으로 예외 처리 코드를 작성해야함.

1) 예외 처리 코드

  • try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우
    예외 처리를 할 수 있도록 해줌

  1. try 블록에는 예외 발생 가능 코드가 위치
  2. try 블록의 코드가 예외 발생 없이 정상 실행되면 catch 블록의 코드는 실행되지 않고
    finally 블록의 코드를 실행
    만약 try 블록의 코드에서 예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행
    그리고 finally 블록의 코드를 실행
  3. finally 블록은 생략 가능
    예외 발생 여부와 상관없이 항상 실행할 내용이 있을 경우에만 finally 블록을 작성해주면 됨
    심지어 try 블록과 catch 블록에서 return문을 사용하더ㄹ도 finally 블록은 항상 실행됨
일반 예외 처리
package sec01.exam06;


public class TryCatchFinallyExample {
public static void main(String[] args) {
try {
Class clazz = Class.forName("String2");
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다.");
}
}
}
클래스가 존재하지 않습니다.
실행 예외 처리
package sec01.exam07;


public class TryCatchFinallyRuntimeExceptionExample {
public static void main(String[] args) {
String data1 = null;
String data2 = null;
try {
data1 = args[0];
data2 = args[1];
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
return;
}

try {
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
}
}
실행 매개값의 수가 부족합니다.

2) 예외 종류에 따른 처리 코드

(1) 다중 catch

  • try 블록 내부는 다양한 예외가 발생할 수 있음
  • 이럴 때 다중 catch 블록을 작성
  • catch 블록의 예외 클래스 타입은 try 블록에서 발생된 예외의 종류를 말하는데,
    try 블록에서 해당 타입의 예외가 발생하면 catch 블록을 실행하도록 되어 있음

  • catch 블록이 여러 개라 할지라도 단 하나의 catch 블록만 실행됨
  • try 블록에서 동시 다발적으로 예외가 발생하지 않고,
    하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동하기 때문
다중 catch
package sec01.exam08;


public class CatchByExceptionKindExample {
public static void main(String[] args) {
try {
String data1 = args[0];
String data2 = args[1];
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다..");
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
}
}
실행 매개값의 수가 부족합니다.
다시 실행하세요.

(2) catch 순서

  • 다중 catch 블록을 작성할 때 주의할 점은 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야한다.
  • try 블록에서 예외가 발생했을 때, 예외를 처리해줄 catch 블록은 위에서부터 차례대로 검색됨.
  • 만약 상위 예외 클래스의 catch 블록이 위에 있다면, 하위 예외 클래스의 catch 블록은 실행되지 않음
  • 하위 예외는 상위 예외를 상속했기 때문에 상위 예외 타입도 되기 때문
CatchOrderExample.java
package sec01.exam09;


public class CatchOrderExample {
public static void main(String[] args) {
try {
String data1 = args[0];
String data2 = args[1];
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + "+" + data2 + "=" + result);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
} catch(Exception e) {
System.out.println("실행에 문제가 있습니다.");
} finally {
System.out.println("다시 실행하세요.");
}
}
}
실행 매개값의 수가 부족합니다.
다시 실행하세요.

3) 예외 떠넘기

  • 메소드 내부에서 예외가 발생할 수 있는 코드를 작성할 때 try-catch 블록으로 예외를 처리하는 것이 기본
    경우에 따라서는 메소드를 호출한 곳으로 예외를 떠넘길 수도 있음
  • 이때 사용하는 키워드가 throws임.
  • throws 키워드
    • 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 함
    • throws 키워드 뒤에는 떠넘길 예외 클래스를 쉼표로 구분해서 나열!

  • 발생할 수 있는 예외의 종류별로 throws 뒤에 나열하는 것이 일반적이지만,
    다음과 같이 throwsException만으로 모든 예외를 간단히 떠넘길 수도 있

  • throws 키워드가 붙어 있는 메소드는 반드시 try블록 내에서 호출되어야함
  • catch 블록에서 떠넘겨 받은 예외를 처리해야함.
예외 처리 떠넘기기
package sec01.exam10;


public class ThrowsExample {
public static void main(String[] args) {
try {
findClass();
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니.");
}
}

public static void findClass() throws ClassNotFoundException {
Class clazz = Class.forName("java.lang.String2");
}
}

Chap 11 기본 API 클래스

1. java.lang 패키지

  • 자바 프로그램의 기본적인 클래스를 담고 있는 패키지
  • java.lang 패키지에 있는 클래스와 인터페이스는 import  없이 사용할 수 있음
  • 지금까지 사용한 String과 System 클래스도 java.lang 패키지에 포함되어 있기 때문에
    import하지 않고 사용했음.

 

  • java.lang 패키지에 속하는 주요 클래스와 간략한 용도
클래스 용도
Object - 자바클래스의 최상위 클래스로 사용
System - 표준 입출력 장치(키보드)로부터 데이터를 입력받을 때 사용
- 표준 출력 장치(모니터)로 출력하기 위해 사용
- 자바 가상 기계를 종료할 때 사용
- 쓰레기 수집기를 실행 요청할 때 사용
Class - 클래스를 메모리로 로딩할 때 사용
String - 문자열을 저장하고 여러 가지 정보를 얻을 때 사용
Wrapper Byte, Short, Character
Integer, Float, Double
Boolean, Long
- 기본 타입의 데이터를 갖는 객체를 만들 때 사용
- 문자열을 기본 타입으로 변환할 때 사용
- 입력값 검사에 사용
Math - 수학 함수를 이용할 때 사용

 

 

1) 자바 API 도큐먼트

  • API: 라이브러리라고 부르기도 함
  • 프로그램 개발에 자주 사용되는 클래스 및 인터페이스의 모음
  • String 클래스와 System 클래스도 모두 API에 속하는 클래스
  • https://docs.oracle.com/en/java/javase/index.html
  • 이클립스에서  String 클래스를 마우스로 선택한 다음 F1을 누르면
    자동으로 API 도큐먼트를 보여주는 Help 뷰가 나타남
  • Help 뷰에서 Javadoc for 'java.lang.String' 링크를 클릭하면 다음과 같이
    Class String 페이지로 이

2) API 도큐먼트에서 클래스 페이지 읽는 방법

  1. 최상단의 SUMMARY: NESTED|FIELD|CONSTR|METHOD
    • SUMMARY는 클래스 내에 선언된 멤버가 무엇이 있는지 알려줌
    • 링크가 있으면 해당 멤버가 있다는 뜻이고 링크가 없으면 클래스 내에 선언된 멤버가 없다는 뜻
    • String 클래스는 NESTED에 링크가 없으므로 중첩 클래스나 중첩 인터페이스가 없다는 뜻
    • FIELD, CONSTR, METHOD는 모두 링크가 있으므로, public 또는 protected로 선언된
      필드, 생성자, 메소드가 있다는 뜻
  2. 클래스의 선언부를 보자
    • 클래스가 final 또는 abstract 키워드가 있는지 확인!
    • String 클래스는 final 키워드가 있으므로 부모 클래스로는 사용할 수 없다
    • extends 뒤에 언급된 부모 클래스를 보자
    • String 클래스는 Object를 상속받고 있음
    • 상속 관계에 있는 모든 클래스를 보려면 위의 상속 계층도를 보면 됨
    • implements 키워드 뒤에 언급된 인터페이스가 무엇인지 보면 String 클래스는 Serializable, Comparable<String>, CharSequence와 같이 3개의 인터페이스를 구현하고 있음
  3. 클래스에 선언된 필드 목록을 보자.
    • 1번에서 설명한 SUMMARY: NESTED | FIELD | CONSTR | METHOD에서 FIELD 링크를 클릭하면 필드 목록으로 이동한다.
    • String 클래스에서 선언된 필드 목록은 다음과 같음
    • Modifier and Type 컬럼에는 static 또는 protected 여부와 타입이 표시됨
    • Description 컬럼에는 필드 이름이 굵은 글씨로 표시되어 있고,
      아래에는 필드에 대한 설명이 있음
      필드 이름을 클릭하면 상세 설명 페이지로 이동함
  4. 클래스에 선언된 생성자 목록을 보자.
    • SUMMARY: NESTED | FIELD | CONSTR | METHOD에서 CONSTR 링크를 클릭하면 생성자 목록으로 이동한다.
    • String 클래스에서 선언된 생성자 목록은 다음과 같음
    • String 클래스에는 매개 변수 타입 또는 개수를 달리해서 10개가 넘는 생성자들이 오버로딩 되어 있다
    • 모두 new 연산자로 호출해서 String 객체를 생성할 수 있음
    • 굵게 표시된 것이 생성자 이름이고, 옆에 간단한 설명이 있음
    • 생성자 이름을 클릭하면 상세 설명 페이지로 이동
  5. 클래스에 선언된 메소드 목록을 보자.
    • SUMMARY: NESTED | FIELD | CONSTR | METHOD에서 
      METHOD 링크를 클릭하면 메소드 목록으로 이동한다.
    • String 클래스에서 선언된 메소드 목록은 다음과 같음
    • [All Methods] 탭은 전체 메소드 목록을 보여주고,
      [Static Methods] 탭은 정적 메소드 목록을 보여줌
    • [Instance Methods] 탭은 인스턴스 메소드 목록을 보여줌
    • Modifier and Type 컬럼에는 static 또는 protected 여부와 리턴 타입이 표시됨
    • static이 없다면 인스턴스 메소드라는 뜻이고, protected가 없다면 기본이 public
    • Method와 Description 컬럼에는 메소드 이름과 매개 변수가 굵으 글씨로 표시되어 있고,
      옆에는 메소드에 대한 간단한 설명이 있음
    • 메소드 이름을 클릭하면 상세 설명 페이지로 이동함

 

3) Object 클래스

  • 클래스를 선언할 때 extends 키워드로 다른 클래스를 상속하지 않더라도 암시적으로
    java.lang.Object 클래스를 상속하게 됨
  • 자바의 모든 클래스는 Object 클래스의 자식이거나 자손 클래스임
  • Object는 자바의 최상위 부모 클래스

  • SUMMARY를 보면 Object 클래스는 필드가 없고, 생성자와 메소드로 구성되어 있음
  • 모든 클래스의 최상위 부모가 Object이므로 모든 클래스에서 Object의 메소드를 사용할 수 있음

(1) 객체 비교(equals())

  • 다음은 Object 클래스의 equals() 메소드

  • equal() 메소드의 매개 타입은 Object인데, 이것은 모든 객체가 매개값으로 대입될 수 있음을 말함.
  • 모든 객체는 Object 타입으로 자동 타입 변환될 수 있기 때문
  • Object 클래스의 equals() 메소드는 비교 연산자인 ==과 동일한 결과를 리턴
  • 두 객체가 동일한 객체라면 true를 리턴하고 그렇지 않으면 false를 리턴
객체 동등 비교(equals() 메소드) // Member.java
package sec01.exam02;


public class Member {
public String id;

public Member(String id) {
this.id = id;
}

@Override
public boolean equals(Object obj) {
if(obj instanceof Member) {
Member member = (Member) obj;
if(id.equals(member.id)) {
return true;
}
}
return false;
}
}
객체 동등 비교(equals() 메소드) // MemberExample.java
package sec01.exam02;


public class MemberExample {
public static void main(String[] args) {
Member obj1 = new Member("blue");
Member obj2 = new Member("blue");
Member obj3 = new Member("red");

if(obj1.equals(obj2)) {
System.out.println("obj1과 obj2는 동등합니다.");
} else {
System.out.println("obj1과 obj2는 동등하지 않습니다.");
}

if(obj1.equals(obj3)) {
System.out.println("obj1과 obj3은 동등합니다.");
} else {
System.out.println("obj1과 obj3은 동등하지 않습니다.");
}
}
}
obj1과 obj2는 동등합니다.
obj1과 obj3은 동등하지 않습니다.

 

(2) 객체 해시코드(hashCode())

  • 객체 해시코드란 객체를 식별하는 하나의 정수값을 말함
  • Object 클래스의 hasCode() 메소드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에
    객체마다 다른 값을 가지고 있음
  • 논리적 동등 비교 시 hashCode()를 오버라이딩할 필요가 있는데,
    컬렉션 프레임워크에서 HashSet, HashMap, Hashtable은 다음과 같은 방법으로 두 객체가 동등한지 비교
  • hasCode() 메소드를 실행해서 리턴된 해시코드 값이 같은지 본다
  • 해시코드 값이 다르면 다른 객체로 판단하고, 해시코드 값이 같으면 equals() 메소드로 다시 비교
  • 따라서 hashCode() 메소드가 true가 나와도 equals()의 리턴값이 다르면 다른 객체가 됨

 

hashCode() 메소드를 재정의하지 않음 //Key.java
package sec01.exam03;


public class Key {
public int number;

public Key(int number) {
this.number = number;
}

@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key) obj;
if(this.number == compareKey.number) {
return true;
}
}
return false;
}
}
  • 이런 경우 HashMap의 식별키로 Key 객체를 사용하면 저장된 값을 찾아오지 못함
  • number 필드값이 같더라도 hashCode() 메소드에서 리턴하는 해시코드가 다르므로 다른 식별키로 인식하기 때문
다른 키로 인식 // KeyExample.java
package sec01.exam03;


import java.util.HashMap;


public class KeyExample {
public static void main(String[] args) {
//Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성
HashMap<Key, String> hashMap = new HashMap<Key, String>();


//식별키 new Key(1) "홍길동"을 저장함
hashMap.put(new Key(1), "홍길동");


//식별키 new Key(1) "홍길동"을 읽어옴
String value = hashMap.get(new Key(1));
System.out.println(value);
}
}
null 

 

  • 의도한 대로 "홍길동"을 읽으려면 다음과 같이 재정의한 hashCode() 메소드를 Key 클래스에 추가하면 됨.
  • hashCode()의 리턴값을 number 필드값으로 했기 때문에 저장할 때의 new Key(1)과 읽을 때의 new Key(1)로 같은 해시코드가 리턴
hashCode() 메소드 재정의 추가 Key.java
package sec01.exam03;


public class Key {
public int number;

public Key(int number) {
this.number = number;
}

@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key) obj;
if(this.number == compareKey.number) {
return true;
}
}
return false;
}

@Override
public int hashCode() {
return number;
}
}
홍길동

 

(3) 객체 문자 정보 (toString())

  • Object 클래스의 toString() 메소드는 객체의 문자 정보를 리턴한다.
  • 객체의 문자 정보란 객체를 문자열로 표현한 값을 말함
  • 기본적으로 Object 클래스의 toString() 메소드는 '클래스이름@16진수해시코드'로 구성된 문자 정보 리턴
객체의 문자 정보(toString() 메소드) ToStringExample.java
package sec01.exam05;


import java.util.Date;


public class ToStringExample {
public static void main(String[] args) {
Object obj1 = new Object();
Date obj2 = new Date();
System.out.println(obj1.toString());
System.out.println(obj2.toString());
}
}
java.lang.Object@6e2c634b
Tue Feb 06 18:43:20 KST 2024
객체의 문자 정보(toString() 메소드) SmartPhone.java
package sec01.exam06;


public class SmartPhone {
private String company;
private String os;

public SmartPhone(String company, String os) {
this.company = company;
this.os = os;
}

@Override
public String toString() {
return company + ", " + os;
}
}
java.lang.Object@6e2c634b
Tue Feb 06 18:45:15 KST 2024
객체의 문자 정보(toString() 메소드) SmartPhoneExample.java
package sec01.exam06;


public class SmartPhoneExample {
public static void main(String[] args) {
SmartPhone myPhone = new SmartPhone("구글", "안드로이드");

String strObj = myPhone.toString();
System.out.println(strObj);

System.out.println(myPhone);
}
}
구글, 안드로이드
구글, 안드로이드

 

4) System 클래스

  • 자바 프로그램은 운영체제에서 바로 실행되는 것이 아니라 JVM 위에서 실행됨
  • 따라서 운영체제의 모든 기능을 이용하기 어렵지만 java.lang 패키지에 속하는 System 클래스를 이용하면
    운영체제의 일부 기능을 이용할 수 있다.
  • 즉, 프로그램 종료, 키보드로부터 입력, 모니터로 출력, 현재 시간 읽기 등이 가능
  • System 클래스의 모든 필드와 메소드는 정적 필드와 정적 메소드로 구성됨

 

(1) 프로그램 종료(exit())

  • System 클래스의 exit() 메소드를 호출
  • 현재 실행하고 있는 프로세스를 강제 종료시키는 역할
  • int 매개값을 지정하도록 되어 있는데, 이 값을 종료 상태값이라고 한다.
  • 일반적으로 정상 종료일 경우 0 값을 줌
ExitExample.java
package sec01.exam07;

public class ExitExample {
public static void main(String[] args) {
for(int i=0; i<10; i++) {
if(i == 5) {
System.exit(i);
//break;
}
}
System.out.println("마무리 코드");
}
}

 

(2) 현재 시각 읽기(currentTimeMillis(), nanoTime())

  • System 클래스의 currentTimeMillis() 메소드와 nanoTime() 메소드는 컴퓨터의 시계로부터 현재 시간을 읽어서
    밀리세컨드(1/1000초) 단위와 나노세컨드(1/1000000000) 단위의 long 값을 리턴합니다. 

SystemTimeExample.java
package sec01.exam08;


public class SystemTimeExample {
public static void main(String[] args) {
long time1 = System.nanoTime();

int sum = 0;
for(int i=1; i<=1000000; i++) {
sum += i;
}

long time2 = System.nanoTime();

System.out.println("1~1000000까지의 합: " + sum);
System.out.println("계산에 " + (time2-time1) + " 나노초가 소요되었습니다.");
}
}
1~1000000까지의 합: 1784293664
계산에 4080200 나노초가 소요되었습니다.

 

5) Class 클래스

  • 자바는 클래스와 인터페이스의 메타 데이터를 java.lang 패키지에 소속된 Class 클래스로 관리함.
  • 메타 데이터란 클래스의 이름, 생성자 정보, 필드 정보 메소드 정보 등을 말함

(1) Class 객체 얻기(getClass(), forName())

  • 프로그램에서 Class 객체를 얻기 위해서는 다음 세 가지 방법 중 하나를 이용하면 된다

  • 첫 번째와 두 번째 방법은 객체 없이 클래스 이름만 가지고 Class 객체를 얻는 방법
  • 세 번째 방법은 클래스로부터 객체가 이미 생성되어 있을 경우에 사용
  • String 클래스의 Class 객체는 다음과 같이 얻을 수 있음

  • 다음은 세 가지 방법으로 Car 클래스의 Class 객체를 얻고, Class의 메소들 이용해 클래스의 전체 이름과 간단한 이름 그리고 패키지 이름을 얻어 출력함.
Class 객체 정보 얻기
package sec01.exam09;


public class ClassExample {
public static void main(String[] args) throws Exception {
//how1
Class clazz = Car.class;

//how2
//Class clazz = Class.forName("sec01.exam09.Car");

//how3
//Car car = new Car();
//Class clazz = car.getClass();

System.out.println(clazz.getName());
System.out.println(clazz.getSimpleName());
System.out.println(clazz.getPackage().getName());
}
}
sec01.exam09.Car
Car
sec01.exam09

 

(2) Class 경로를 활용해서 리소스 절대 경로 얻기

리소스 절대 경로 얻기 ResourcePathExample.java
package sec01.exam10;


public class ClassExample {
public static void main(String[] args) {
Class clazz = Car.class;


String photo1Path = clazz.getResource("photo1.jpg").getPath();
String photo2Path = clazz.getResource("images/photo2.jpg").getPath();

System.out.println(photo1Path);
System.out.println(photo2Path);
}
}
/C:/SelfStudyjava/chap11/bin/sec01/exam10/photo1.jpg
/C:/SelfStudyjava/chap11/bin/sec01/exam10/images/photo2.jpg

 

6) String 클래스

(1) String 생성자

바이트 배열을 문자열로 변환
package sec01.exam11;


public class ByteToStringExample {
public static void main(String[] args) {St
byte[] bytes = { 72, 101, 108, 108, 111, 32, 74, 97, 118, 97 };

String str1 = new String(bytes);
System.out.println(str1);

String str2 = new String(bytes, 6, 4);
System.out.println(str2);
}
}
Hello Java
Java
바이트 배열을 문자열로 변환
package sec01.exam12;


import java.io.IOException;


public class KeyboardToStringExample {
public static void main(String[] args) throws IOException {
byte[] bytes = new byte[100];

System.out.print("입력: ");
int readByteNo = System.in.read(bytes);


String str = new String(bytes, 0, readByteNo-2);
System.out.println(str);
}
}
입력: Hello
Hello

(2) String 메소드

  • String 클래스는 문자열의 추출, 비교, 찾기, 분리, 변환 등과 같은 다양한 메소드를 가지고 있다.
주민등록번호에서 남자와 여자를 구분하는 방법
package sec01.exam13;


public class StringCharAtExample {
public static void main(String[] args) {
String ssn = "010624-1230123";
char sex = ssn.charAt(7);
switch (sex) {
case '1':
case '3':
System.out.println("남자 입니다.");
break;
case '2':
case '4':
System.out.println("여자 입니다.");
break;
}
}
}
남자 입니다.
문자열 비교
package sec01.exam13;


public class StringCharAtExample {
public static void main(String[] args) {
String ssn = "010624-1230123";
char sex = ssn.charAt(7);
switch (sex) {
case '1':
case '3':
System.out.println("남자 입니다.");
break;
case '2':
case '4':
System.out.println("여자 입니다.");
break;
}
}
}
다른 String 객체를 참조
같은 문자열을 가짐
바이트 배열로 변환
package sec01.exam15;


import java.io.UnsupportedEncodingException;


public class StringGetBytesExample {
public static void main(String[] args) {
String str = "안녕하세요";


byte[] bytes1 = str.getBytes();
System.out.println("bytes1.length: " + bytes1.length);
String str1 = new String(bytes1);
System.out.println("bytes1->String: " + str1);


try {


byte[] bytes2 = str.getBytes("EUC-KR");
System.out.println("bytes2.length: " + bytes2.length);
String str2 = new String(bytes2, "EUC-KR");
System.out.println("bytes2->String: " + str2);




byte[] bytes3 = str.getBytes("UTF-8");
System.out.println("bytes3.length: " + bytes3.length);
String str3 = new String(bytes3, "UTF-8");
System.out.println("bytes3->String: " + str3);


} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
bytes1.length: 15
bytes1->String: 안녕하세요
bytes2.length: 10
bytes2->String: 안녕하세요
bytes3.length: 15
bytes3->String: 안녕하세요
문자열 포함 여부 조사
package sec01.exam16;


public class StringIndexOfExample {
public static void main(String[] args) {
String subject = "자바 프로그래밍";

int location = subject.indexOf("프로그래밍");
System.out.println(location);

if(subject.indexOf("자바") != -1) {
System.out.println("자바와 관련된 책이군요");
} else {
System.out.println("자바와 관련없는 책이군요");
}
}
}
3
자바와 관련된 책이군요
문자열의 문자 수 얻기
package sec01.exam17;


public class StringLengthExample {
public static void main(String[] args) {
String ssn = "7306241230123";
int length = ssn.length();
if(length == 13) {
System.out.println("주민번호 자리수가 맞습니다.");
} else {
System.out.println(" 주민번호 자리수가 틀립니다.");
}
}
}
주민번호 자리수가 맞습니다.
문자열 대치하기
package sec01.exam18;


public class StringReplaceExample {
public static void main(String[] args) {
String oldStr = "자바는 객체 지향 언어입니다. 자바는 풍부한 API를 지원합니다";
String newStr = oldStr.replace("자바", "JAVA");

System.out.println(oldStr);
System.out.println(newStr);
}
}
자바는 객체 지향 언어입니다. 자바는 풍부한 API를 지원합니다.
JAVA는 객체 지향 언어입니다. JAVA는 풍부한 API를 지원합니다.
문자열 추출하기
package sec01.exam19;


public class StringSubstringExample {
public static void main(String[] args) {
String ssn = "880815-1234567 ";

String firstNum = ssn.substring(0, 6);
System.out.println(firstNum);

String secondNum = ssn.substring(7);
System.out.println(secondNum);
}
}
880805
1234567
전부 소문자 또는 대문자로 변경
package sec01.exam20;


public class StringToLowerUpperCaseExample {
public static void main(String[] args) {
String str1 = "Java Programming";
String str2 = "JAVA Programming";

System.out.println(str1.equals(str2));

String lowerStr1 = str1.toLowerCase();
String lowerStr2 = str2.toLowerCase();
System.out.println(lowerStr1.equals(lowerStr2));

System.out.println(str1.equalsIgnoreCase(str2));
}
}
false
true
true
문자열 앞뒤 공백 제거
package sec01.exam21;


public class StringTrimExample {
public static void main(String[] args) {
String tel1 = " 02";
String tel2 = "123 ";
String tel3 = " 1234 ";

String tel = tel1.trim() + tel2.trim() + tel3.trim();
System.out.println(tel);
}
}
021231234
기본 타입 값을 문자열로 변환
package sec01.exam22;


public class StringValueOfExample {
public static void main(String[] args) {
String str1 = String.valueOf(10);
String str2 = String.valueOf(10.5);
String str3 = String.valueOf(true);

System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
}
}
10
10.5
true

 

7) Wrapper(포장) 클래스

(1) 박싱(Boxing)과 언박싱(Unboxing)

  • 기본 타입의 값을 포장 객체로 만드는 과정을 박싱이라고 하고,
  • 포장 객체에서 기본 타입의 값을 얻어내는 과정을 언박싱이라고 한다.
기본 타입의 값을 박싱하고 언박싱하기
package sec01.exam23;


public class BoxingUnBoxingExample {
public static void main(String[] args) {
//Boxing
Integer obj1 = new Integer(100);
Integer obj2 = new Integer("200");
Integer obj3 = Integer.valueOf("300");

//Unboxing
int value1 = obj1.intValue();
int value2 = obj2.intValue();
int value3 = obj3.intValue();

System.out.println(value1);
System.out.println(value2);
System.out.println(value3);
}
}
100
200
300

(2) 자동 박싱과 언박싱

AutoBoxingUnBoxingExample.java
package sec01.exam24;


public class AutoBoxingUnBoxingExample {
public static void main(String[] args) {
//자동 Boxing
Integer obj = 100;
System.out.println("value: " + obj.intValue());


//대입 시 자동 Unboxing
int value = obj;
System.out.println("value: " + value);


//연산 시 자동 Unboxing
int result = obj + 100;
System.out.println("result: " + result);
}
}
value: 100
value: 100
result: 200
문자열을 기본 타입 값으로 변환
package sec01.exam25;


public class StringToPrimitiveValueExample {
public static void main(String[] args) {
int value1 = Integer.parseInt("10");
double value2 = Double.parseDouble("3.14");
boolean value3 = Boolean.parseBoolean("true");

System.out.println("value1: " + value1);
System.out.println("value2: " + value2);
System.out.println("value3: " + value3);
}
}
value1: 10
value2: 3.14
value3: true

(3) 포장 값 비교

포장 객체 비교
package sec01.exam26;


public class ValueCompareExample {
public static void main(String[] args) {
System.out.println("[-128~127 초과값일 경우]");
Integer obj1 = 300;
Integer obj2 = 300;
System.out.println("==결과: " + (obj1 == obj2));
System.out.println("언박싱후 ==결과: " + (obj1.intValue() == obj2.intValue()));
System.out.println("equals() 결과: " + obj1.equals(obj2));
System.out.println();


System.out.println("[-128~127 범위값일 경우]");
Integer obj3 = 10;
Integer obj4 = 10;
System.out.println("==결과: " + (obj3 == obj4));
System.out.println("언박싱후 ==결과: " + (obj3.intValue() == obj4.intValue()));
System.out.println("equals() 결과: " + obj3.equals(obj4));
}
}
[-128~127 초과값일 경우]
==결과: false
언박싱후 ==결과: true
equals() 결과: true


[-128~127 범위값일 경우]
==결과: true
언박싱후 ==결과: true
equals() 결과: true

 

8) Math 클래스

Math의 수학 메소드
package sec01.exam27;


public class MathExample {
public static void main(String[] args) {
int v1 = Math.abs(-5);
double v2 = Math.abs(-3.14);
System.out.println("v1=" + v1);
System.out.println("v2=" + v2);


double v3 = Math.ceil(5.3);
double v4 = Math.ceil(-5.3);
System.out.println("v3=" + v3);
System.out.println("v4=" + v4);

double v5 = Math.floor(5.3);
double v6 = Math.floor(-5.3);
System.out.println("v5=" + v5);
System.out.println("v6=" + v6);

int v7 = Math.max(5, 9);
double v8 = Math.max(5.3, 2.5);
System.out.println("v7=" + v7);
System.out.println("v8=" + v8);

int v9 = Math.min(5, 9);
double v10 = Math.min(5.3, 2.5);
System.out.println("v9=" + v9);
System.out.println("v10=" + v10);

double v11 = Math.random();
System.out.println("v11=" + v11);

double v12 = Math.rint(5.3);
double v13 = Math.rint(5.7);
System.out.println("v12=" + v12);
System.out.println("v13=" + v13);

long v14 = Math.round(5.3);
long v15 = Math.round(5.7);
System.out.println("v14=" + v14);
System.out.println("v15=" + v15);

double value = 12.3456;
double temp1 = value * 100;
long temp2 = Math.round(temp1);
double v16 = temp2 / 100.0;
System.out.println("v16=" + v16);
}
}
v1=5
v2=3.14
v3=6.0
v4=-5.0
v5=5.0
v6=-6.0
v7=9
v8=5.3
v9=5
v10=2.5
v11=0.9278559285233545
v12=5.0
v13=6.0
v14=5
v15=6
v16=12.35
임의의 주사위의 눈 얻기
package sec01.exam28;


public class MathRandomExample {
public static void main(String[] args) {
int num = (int) (Math.random()*6) + 1;
System.out.println("주사위의 눈: " + num);
}
}
주사위의 눈: 1

 

[ 확인 문제 ]

Student.java StudentExample.java
package sec01.verify.exam03;


public class Student {
private String studentNum;

public Student(String studentNum) {
this.studentNum = studentNum;
}


public String getStudentNum() {
return studentNum;
}


@Override
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student student = (Student) obj;
if(studentNum.equals(student.getStudentNum())) {
return true;
}
}
return false;
}

@Override
public int hashCode() {
return studentNum.hashCode();
}
}
package sec01.verify.exam03;


import java.util.HashMap;


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

HashMap<Student, String> hashMap = new HashMap<Student, String>();


hashMap.put(new Student("1"), "95");


String score = hashMap.get(new Student("1"));
System.out.println("1번 학생의 총점: " + score);
}
}

'

Member.java MemberExample.java
package sec01.verify.exam04;


public class Member {
private String id;
private String name;

public Member(String id, String name) {
this.id = id;
this.name = name;
}

@Override
public String toString() {
return id + ": " + name;
}
}
package sec01.verify.exam04;


public class MemberExample {
public static void main(String[] args) {
Member member = new Member("blue", "이파란");
System.out.println(member);
}
}

BytesToStringExample.java
package sec01.verify.exam06;


public class BytesToStringExample {
public static void main(String[] args) {
byte[] bytes = { 73, 32, 108, 111, 118, 101, 32, 121, 111, 117 };
String str = new String(bytes);
System.out.println( str );
}
}

FindAndReplaceExample.java
package sec01.verify.exam07;


public class FindAndReplaceExample {
public static void main(String[] args) {
String str = "모든 프로그램은 자바 언어로 개발될 수 있다.";
int index = str.indexOf("자바");
if(index == -1) {
System.out.println("자바 문자열이 포함되어 있지 않습니다.");
} else {
System.out.println("자바 문자열이 포함되어 있습니.");
str = str.replace("자바", "Java");
System.out.println("-->" + str);
}
}
}

 

  • 값의 범위가 -128 ~127이면 ==은 값을 비교하고 그 외이면 번지를 비교

 

package sec01.verify.exam09;


public class StringConvertExample {
public static void main(String[] args) {
String strData1 = "200";
int intData1 = Integer.parseInt(strData1);

int intData2 = 150;
String strData2 = String.valueOf(intData2);
}
}

 

 

2. java.util 패키지

  • 자바 표준 api에는 날짜 정보와 관련된 클래스들이 있다.

1) Date 클래스

  • 날짜와 시간 정보를 저장하는 클래스
  • 특정 시점의 날짜를 표현하는 클래스
  • Date 객체 안에는 특정 시점의 연도, 월, 일, 시간 정보가 저장
현재 날짜 출력하기 DateExample.java
package sec02.exam01;

import java.text.*;
import java.util.*;

public class DateExample {
public static void main(String[] args) {
Date now = new Date();
String strNow1 = now.toString();
System.out.println(strNow1);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일 hh시 mm분 ss초");
String strNow2 = sdf.format(now);
System.out.println(strNow2);
}
}
Tue Feb 06 20:50:58 KST 2024
2024년 02월 06일 08시 50분 58초

2) Calendar 클래스

  • 운영체제의 날짜와 시간을 얻을 때 사용
  • 달력을 표현한 클래스
  • 해당 운영체제의 Calendar 객체를 얻으면, 연도, 월, 일, 요일, 오전/오후, 시간 등의 정보를 얻을 수 있음
운영체제의 시간대를 기준으로 Calendar 얻기
package sec02.exam02;


import java.util.*;


public class CalendarExample {
public static void main(String[] args) {
Calendar now = Calendar.getInstance();

int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH) + 1;
int day = now.get(Calendar.DAY_OF_MONTH);

int week = now.get(Calendar.DAY_OF_WEEK);
String strWeek = null;
switch(week) {
case Calendar.MONDAY:
strWeek = "월";
break;
case Calendar.TUESDAY:
strWeek = "화";
break;
case Calendar.WEDNESDAY:
strWeek = "수";
break;
case Calendar.THURSDAY:
strWeek = "목";
break;
case Calendar.FRIDAY:
strWeek = "금";
break;
case Calendar.SATURDAY:
strWeek = "토";
break;
default:
strWeek = "일";
}

int amPm = now.get(Calendar.AM_PM);
String strAmPm = null;
if(amPm == Calendar.AM) {
strAmPm = "오전";
} else {
strAmPm = "오";
}

int hour = now.get(Calendar.HOUR);
int minute = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);


System.out.print(year + "년 ");
System.out.print(month + "월 ");
System.out.println(day + "일 ");
System.out.print(strWeek + "요일 ");
System.out.println(strAmPm + " ");
System.out.print(hour + "시 ");
System.out.print(minute + "분 ");
System.out.println(second + "초 ");
}
}
2024년 2월 6일
화요일 오후
8시 55분 0초

 

'

package sec02.verify.exam01;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DatePrintExample {
public static void main(String[] args) {
Date now = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일  E요일 HH시 mm분");
System.out.println( sdf.format(now) );
}
}

 

package sec02.verify.exam02;


import java.util.Calendar;


public class DatePrintExample {
public static void main(String[] args) {
Calendar now = Calendar.getInstance();

int year = now.get(Calendar.YEAR);

int month = now.get(Calendar.MONTH) + 1;
String strMonth = (month<10)? ("0"+month) : (""+month);

int dayOfMonth = now.get(Calendar.DAY_OF_MONTH);
String strDayOfMonth = (dayOfMonth<10)? ("0"+dayOfMonth) : (""+dayOfMonth);

String[] dayArray = {"일", "월", "화", "수", "목", "금", "토"};
int dayOfWeek = now.get(Calendar.DAY_OF_WEEK);
String strDayOfWeek = dayArray[dayOfWeek-1] + "요";

int hour = now.get(Calendar.HOUR_OF_DAY);
String strHour = (hour<10)? ("0"+hour) : (""+hour);

int second = now.get(Calendar.SECOND);
String strSecond = (second<10)? ("0"+second) : (""+second);

System.out.print(year + "년 ");
System.out.print(strMonth + "월 ");
System.out.print(strDayOfMonth + "일 ");
System.out.print(strDayOfWeek + " ");
System.out.print(strHour + "시 ");
System.out.print(strSecond + "분 ");
}
}

 

 

 

[ 기본미션 :: 확인문제 9-2-2 ]

package sec02.verify.exam02;


public interface Vehicle {
public void run();
}
package sec02.verify.exam02;


public class Anonymous {
Vehicle field = new Vehicle() {
@Override
public void run() {
System.out.println("자전거가 달립니다.");
}
};


void method1() {
Vehicle localVar = new Vehicle() {
@Override
public void run() {
System.out.println("승용차가 달립니다.");
}
};
localVar.run();
}

void method2(Vehicle v) {
v.run();
}
}
package sec02.verify.exam02;


public class AnonymousExample {
public static void main(String[] args) {
Anonymous anony = new Anonymous();
anony.field.run();
anony.method1();
anony.method2(
new Vehicle() {
@Override
public void run() {
System.out.println("트럭이 달립니다.");
}
}
);
}
}

 

    • 익명 클래스를 활용하여 인터페이스를 구현하는 방법
    • 익명 클래스를 사용하여 인터페이스를 구현하고, 해당 인터페이스의 메소드를 호출함
    • Vehicle 인터페이스는 run() 메서드를 정의
    • Anonymous 클래스
      • Vehicle 타입의 field 멤버 변수가 있다
      • 변수는 익명 클래스를 사용하여 run() 메서드를 구현하며 이 클래스의 인스턴스는 field에 할당됨.
      • method1() 메서드는 Vehicle 타입의 로컬 변수 localVar을 선언. 이 변수도 익명 클래스를 사용하여 run() 메서드를 구현하며, 그 내용은 "승용차가 달립니다."를 출력
      • method2() 메서드는 Vehicle 인터페이스를 구현한 객체를 매개변수로 받아서 해당 객체의 run() 메서드를 호출
    • AnonymousExample 클래스
      • main() 메서드에서 Anonymous 클래스의 인스턴스를 생성
      • field의 run() 메서드를 호출하여 "자전거가 달립니다."를 출력
      • method1()을 호출하여 "승용차가 달립니다."를 출력
      • method2()를 호출하는데, 여기에는 익명 클래스를 사용하여 "트럭이 달립니다."를 출력하는 객체가 전달됨됨

 

728x90
반응형