JAVA - 8

Date:

카테고리:

태그:

img

익명클래스 사용

Java에서 익명 클래스를 사용하는 예시입니다.

Anony라는 인터페이스가 정의되어 있습니다. 이 인터페이스는 print()라는 추상 메서드를 가지고 있습니다.

AnonyTest 클래스는 printB(Anony a)라는 메서드를 정의하고 있습니다. 이 메서드는 Anony 타입의 인자 a를 받아서 a.print()를 호출하는 역할을 합니다.

main() 메서드에서 AnonyTest 클래스의 인스턴스 t를 생성합니다. 그리고 t.printB() 메서드를 호출하는데, 이 때 익명 클래스를 사용합니다.

new Anony() {...} 구문은 Anony 인터페이스를 구현한 익명 클래스의 인스턴스를 생성하는 코드입니다. 중괄호 안에는 print() 메서드를 구현하고 그 안에서 출력문을 실행하는 내용이 작성되어 있습니다.

위의 코드에서는 두 번의 t.printB() 호출이 있습니다. 첫 번째 호출은 “익명 클래스 사용 중입니다.”라는 출력을, 두 번째 호출은 “안녕하세요.”라는 출력을 하게 됩니다.

이처럼 익명 클래스는 인터페이스나 추상 클래스를 구현하여 간단한 구현을 필요로 할 때 유용하게 사용될 수 있습니다.

MultiTest.java

Java에서 다중 인터페이스와 상속을 사용하는 예시입니다.

  • ITest3 인터페이스는 func1()이라는 추상 메서드를 가지고 있습니다.
  • ITest2 인터페이스는 ITest3를 상속하며, func1() 메서드를 재정의합니다.
  • ITest1 인터페이스는 test()라는 추상 메서드를 가지고 있습니다.
  • Child 클래스는 ITest1ITest2를 구현합니다. 따라서 Child 클래스는 test(), func1(), func2() 메서드를 구현해야 합니다.

main() 메서드에서는 다음과 같은 작업을 수행합니다:

  1. Child 클래스의 인스턴스 c를 생성합니다.
  2. ITest1 타입의 인터페이스 변수 i1을 선언하고, Child 인스턴스를 할당합니다.
  3. ITest2 타입의 인터페이스 변수 i2를 선언하고, Child 인스턴스를 할당합니다.
  4. c 객체의 test(), func1(), func2() 메서드를 호출하여 각각의 결과를 출력합니다.
  5. i1 객체의 test() 메서드를 호출하여 결과를 출력합니다. i1ITest1 타입이기 때문에 func1()func2()를 호출할 수 없습니다.
  6. i2 객체의 func1() 메서드를 호출하여 결과를 출력합니다.

제네릭

제네릭 2 - 단일 인자

MyClass<T>는 제네릭 클래스로, 타입 매개변수 T를 사용합니다. 제네릭 클래스는 어떤 타입을 사용할 것인지를 나중에 결정할 수 있도록 합니다.

MyClass 클래스는 private T t;public void set(T t) 메서드, 그리고 public T get() 메서드를 가지고 있습니다. set() 메서드는 제네릭 타입 T의 인자를 받아서 t 필드에 할당하고, get() 메서드는 t 필드를 반환합니다.

main() 메서드에서는 다음과 같은 작업을 수행합니다:

  1. MyClass<String> 타입의 인스턴스 mc1을 생성합니다. 이 때 TString으로 결정됩니다.
  2. mc1 객체의 set("안녕") 메서드를 호출하여 값을 설정합니다.
  3. mc1 객체의 get() 메서드를 호출하여 설정된 값을 출력합니다.
  4. MyClass<Integer> 타입의 인스턴스 mc2를 생성합니다. 이 때 TInteger로 결정됩니다.
  5. mc2 객체의 set(100) 메서드를 호출하여 값을 설정합니다.
  6. mc2 객체의 get() 메서드를 호출하여 설정된 값을 출력합니다.
  7. 주석 처리된 코드는 컴파일 오류를 발생시킵니다. mc3MyClass<Integer> 타입으로 선언되었기 때문에, set() 메서드에 문자열을 전달할 수 없습니다. 이는 제네릭의 강한 타입 체크에 의해 발생하는 오류입니다.

제네릭3 - 다중 인자

Java에서 두 개의 제네릭 인자를 사용하는 예시입니다.

KeyValue<Key, Value>는 제네릭 클래스로, 두 개의 타입 매개변수 KeyValue를 사용합니다. 이 클래스는 keyvalue라는 필드를 가지고 있습니다.

getKey()setKey() 메서드는 key 필드에 접근하는 메서드이고, getValue()setValue() 메서드는 value 필드에 접근하는 메서드입니다.

main() 메서드에서는 다음과 같은 작업을 수행합니다:

  1. KeyValue<String, Integer> 타입의 인스턴스 kv1을 생성합니다. KeyString 타입, ValueInteger 타입으로 결정됩니다.
  2. kv1 객체의 setKey("사과")setValue(10000) 메서드를 호출하여 키와 값을 설정합니다.
  3. kv1 객체의 getKey()getValue() 메서드를 호출하여 설정된 키와 값을 가져옵니다.
  4. KeyValue<Integer, String> 타입의 인스턴스 kv2를 생성합니다. KeyInteger 타입, ValueString 타입으로 결정됩니다.
  5. kv2 객체의 setKey(404)setValue("Not Found(요청한 페이지를 찾을 수 없습니다.)") 메서드를 호출하여 키와 값을 설정합니다.
  6. kv2 객체의 getKey()getValue() 메서드를 호출하여 설정된 키와 값을 가져옵니다.
  7. KeyValue<String, Void> 타입의 인스턴스 kv3를 생성합니다. KeyString 타입, ValueVoid 타입으로 결정됩니다. Void 타입은 null만 가질 수 있는 타입입니다.
  8. kv3 객체의 setKey("키값만 사용") 메서드를 호출하여 키 값을 설정합니다.
  9. kv3 객체의 getKey() 메서드를 호출하여 설정된 키 값을 가져옵니다.

예외 처리

다중 catch문을 사용하여 예외 처리하는 예시입니다.

다중 catch문은 여러 종류의 예외를 처리하기 위해 사용됩니다. 코드 블록 안에서 예외가 발생할 수 있는 부분을 try 블록으로 감싸고, 발생한 예외에 따라 적절한 처리를 위해 catch 블록을 사용합니다.

코드의 실행 흐름은 다음과 같습니다:

  1. try 블록 안에서 배열 num을 생성하고, 인덱스 0과 1에 값을 할당합니다.
  2. num[2] = 3에서 ArrayIndexOutOfBoundsException 예외가 발생합니다. 이 예외는 배열 인덱스 범위를 벗어났을 때 발생합니다.
  3. 예외 발생 후, 해당하는 catch 블록 중에서 해당 예외 타입과 일치하는 블록을 찾습니다. 첫 번째 catch 블록(ArrayIndexOutOfBoundsException)에 해당하므로, 해당 블록 안의 코드가 실행됩니다. “ArrayIndexOutOfBoundsException 처리”라는 메시지가 출력됩니다.
  4. catch 블록 실행 후, 프로그램은 catch 블록 이후의 코드인 System.out.println("World")를 실행합니다. “World”가 출력됩니다.

다중 catch문에서 주의해야 할 점은 예외 클래스의 계층 구조에 따라 순서를 지정해야 한다는 점입니다. 상위 예외 클래스 타입을 가지는 catch 블록은 하위 예외 클래스 타입보다 뒤에 위치해야 합니다. 이는 상위 예외 클래스가 하위 예외 클래스의 부모 클래스이기 때문에, 상위 예외 클래스 타입의 catch 블록을 먼저 작성하면 모든 예외를 처리할 수 있게 됩니다. 만약 순서를 바꾼다면, 상위 예외 클래스 타입의 catch 블록에서 모든 예외를 처리하게 되고, 하위 예외 클래스 타입의 catch 블록은 실행되지 않습니다.

마지막으로, finally 블록은 예외 발생 여부와 관계없이 항상 실행되는 부분입니다. 위의 코드에는 finally 블록이 없으므로, 예외 발생 여부와 상관없이 “World”가 출력된 이후에 프로그램이 종료됩니다.

예외 처리2 - throw

throws 처리 방식을 사용하여 예외를 처리하는 예시입니다.

메서드에서 예외가 발생할 수 있는 부분을 try 블록으로 감싸고, 예외가 발생한 경우 해당 예외를 메서드를 호출한 곳으로 전달합니다. 이를 위해 예외를 throws 키워드를 사용하여 선언합니다.

위의 코드에서는 ArrayIndexOutOfBoundsException 예외가 발생할 수 있는 부분을 try 블록으로 감싸고, 예외가 발생한 경우 catch 블록에서 해당 예외를 처리합니다. finally 블록은 생략되어 있지만, finally 블록은 예외 발생 여부와 상관없이 항상 실행됩니다.

main() 메서드에서는 try-catch 구문을 사용하여 ArrayIndexOutOfBoundsException 예외를 처리합니다. 따라서 예외 발생 시 “ArrayIndexOutOfBoundsException 오류 발생”이 출력되고, finally 블록이 실행됩니다. 마지막으로 “World”가 출력됩니다.

RuntimeException 계열의 예외는 throws로 선언하지 않아도 됩니다. RuntimeException은 명시적인 예외 처리가 필요하지 않으며, 컴파일러가 체크하지 않습니다.

따라서 위의 코드는 “ArrayIndexOutOfBoundsException 오류 발생”, “오류 발생 유무와 무관하게 반드시 수행된다.”, “World”를 순서대로 출력합니다.

java 카테고리 내 다른 글 보러가기

댓글 남기기