제네릭 제네릭클래스 제네릭인터페이스 제네릭메소드 형매개변수의제한 어노테이션 어노테이션형태시스템정의어노테이션사용자정의어노테이션 kkman@sangji.ac.kr 2
제네릭 (generic) 클래스나메소드에자료형을매개변수형식으로사용할수있는기능 자료형과무관하게알고리즘을기술 예전에작성한알고리즘을쉽게재사용가능 어노테이션 (annotation) 프로그램요소에다양한종류의속성정보를추가하기위해서사용 자바클래스파일에저장 개발도구나자바가상기계, 애플리케이션에서접근가능 kkman@sangji.ac.kr 3
제네릭이란? 변수의형을매개변수로하여클래스나메소드의알고리즘을자료형과무관하게기술하는기법 형매개변수 (type parameter) 클래스내의필드나메소드선언시자료형으로사용 '<' 과 '>' 사이에형매개변수의이름을기술 : <T 1, T 2, T 3,..., T n > 제네릭의장점 알고리즘의재사용성을높임자료형에따른프로그램의중복을줄임프로그램의구조를단순하게만듦 kkman@sangji.ac.kr 4
Object 클래스형을사용한유사제네릭기능 Object 클래스형은모든객체의최상위클래스형이므로, 자바의모든객체를참조할수있음 타입에따라실행시간예외발생 제네릭에관한형검사는컴파일시간에이루어짐 자바의제네릭프로그램의단위 클래스 인터페이스 메소드 kkman@sangji.ac.kr 5
자바이전버전의유사제네릭기능의사용예 형불일치에따른실행시간예외발생 [ 예제 10.1 - StackExample.java] import java.util.*; public class StackExample { public static void main(string[] args) { Stack stk = new Stack(); stk.push(new String("Hello")); ")) // 스택에문자열객체를넣음 Integer i = (Integer)stk.pop(); // 스택에서문자열객체를꺼냄 // i 가가리키는객체는문자열객체이므로, // 실행중에예외발생 System.out.println(i.intValue()); 실행결과 : Exception in thread "main" " java.lang.classcastexception: C java.lang.string cannot be cast to java.lang.integer at StackExample.main(StackExample.java:7) kkman@sangji.ac.kr 6
형매개변수를이용한제네릭의사용예 형불일치에따른컴파일시간에러발생 [ 예제 10.2 - TypedStackExample.java] import java.util.*; public class TypedStackExample { public static void main(string[] args) { Stack<String> stk = new Stack<String>(); stk.push(new String("Hello")); Integer i = (Integer)stk.pop(); // 컴파일에러 System.out.println(i.intValue()); 컴파일결과 : TypedStackExample.java:7: inconvertible types found : java.lang.string required: java.lang.integer 1 error Integer i = (Integer)stk.pop(); ^ kkman@sangji.ac.kr 7
형매개변수 (type parameter) 를가지는클래스 형매개변수를이용하여필드나지역변수에사용 실제형정보는객체생성시에전달받음 정의형태 [modifiers] class ClassName<TypeParameters> { //... class body kkman@sangji.ac.kr 8
형식매개변수형 (formal parameter type) 제네릭클래스를선언할때사용한형매개변수 class SimpleGeneric<T> {... 실제형인자 (actual type argument) 제네릭클래스에대한객체를생성할때주는자료형 new SimpleGeneric<Integer>(10); kkman@sangji.ac.kr 9
제네릭클래스사용의예 클래스정의 [ 예제 10.3 - GenericClassExample.java] class SimpleGeneric<T> { private T[] values; private int index; SimpleGeneric(int len) { // Constructor values = (T[])new Object[len]; index = 0; public void add(t... args) { for (T e : args) values[index++] = e; public void print() { for (T e : values) System.out.print(e + " "); System.out.println(); kkman@sangji.ac.kr 10
제네릭클래스사용의예 - 사용 [ 예제 10.3 - GenericClassExample.java](cont.) public class GenericClassExample { public static void main(string[] i args) ){ SimpleGeneric<Integer> ginteger = new SimpleGeneric<Integer>(10); SimpleGeneric<Double> gdouble = new SimpleGeneric<Double>(10); ginteger.add(1, g 2); ginteger.add(1, 2, 3, 4, 5, 6, 7); ginteger.add(0); ginteger.print(); gdouble.add(10.0, add(100 20.0, 200 30.0); 300); gdouble.print(); 실행결과 : 1 2 1 2 3 4 5 6 7 0 10.0 20.0 30.0 null null null null null null null kkman@sangji.ac.kr 11
형매개변수를가지는인터페이스 형매개변수의선언외에일반인터페이스를구현하는과정과동일 정의형태 [modifiers] interface InterfaceName<TypeParameters> { //... interface body kkman@sangji.ac.kr 12
제네릭인터페이스구현의예 인터페이스정의및구현 [ 예제 10.5 - GenericInterfaceExmaple.java] interface GenericInterface<T> { public void setvalue(t x); public String getvaluetype(); class GenericClass<T> implements GenericInterface<T> { private T value; public void setvalue(t x) { value = x; public String getvaluetype(){ return value.getclass().tostring(); kkman@sangji.ac.kr 13
제네릭인터페이스구현의예 - 사용 [ 예제 10.5 - GenericInterfaceExmaple.java](cont.) public class GenericInterfaceExample { public static void main(string[] args) { GenericClass<Integer> ginteger = new GenericClass<Integer>(); GenericClass<String> gstring = new GenericClass<String>(); ginteger.setvalue(10); gstring.setvalue("text"); System.out.println(gInteger.getValueType()); System.out.println(gString.getValueType()); 실행결과 : class java.lang.integer class java.lang.string kkman@sangji.ac.kr 14
형매개변수를가지는메소드 메소드수정자와반환형사이에형매개변수를삽입하여정의 정의형태 [modifiers] <TypeParameters> return_typetype MethodName(parameters) { //... method body kkman@sangji.ac.kr 15
형매개변수의중첩 제네릭메소드의형매개변수의이름과제네릭클래스의형매개변수이름이같은경우 서로독립된형매개변수의개념을가짐 제네릭클래스는객체생성시에형매개변수를전달받음 제네릭메소드는호출시에유추하여형매개변수가결정됨 kkman@sangji.ac.kr 16
제네릭메소드사용의예 [ 예제 10.6 - GenericMethodExample.java] public class GenericMethodExample { public static <T> void printarginfo(t arg) { System.out.print( print("argument Type is " + arg.getclass()); getclass()); System.out.println(" / Value is " + arg.tostring()); public static void main(string[] args) { Integer i = new Integer(10); char c = 'A'; float f = 3.14f; printarginfo(i); // <Integer> void printarginfo(integer) printarginfo(c); // <Character> void printarginfo(character) printarginfo(f); // <Float> void printarginfo(float) 실행결과 : Argument Type is class java.lang.integer / Value is 10 Argument Type is class java.lang.character / Value is A Argument Type is class java.lang.float / Value is 3.14 kkman@sangji.ac.kr 17
형매개변수의범위 프로그램의유연성 신뢰성 프로그램의신뢰성을증진하기위해제네릭에전달가능한자료형의범위를제한할필요가있음 제네릭클래스를작성시한정 exetneds 키워드와 & 문자사용 <T extends S> - S 형의서브클래스형으로제한한다. <T extends S & I> - S 형의서브클래스형과인터페이스 I 를구현한형으로제한한다. kkman@sangji.ac.kr 18
형매개변수제한의예 [BoundedGenericExample.java] class GenericType<T extends Number> { private T value; GenericType(T v) { value = v; public String tostring() { return "Type is " + value.getclass() + " / Value is " + value.tostring(); public class BoundedGenericExample { public static void main(string[] args) { GenericType<Integer> ginteger = new GenericType<Integer>(10); GenericType<Double> gdouble = new GenericType<Double>(3.14); // GenericType<String> gstring = new GenericType<String>("Error"); // 에러 System.out.println(gInteger.toString()); System.out.println(gDouble.toString()); 실행결과 : Type is class java.lang.integer / Value is 10 Type is class java.lang.double / Value is 3.14 kkman@sangji.ac.kr 19
형매개변수사용시한정 '?' 문자 <?> - 모든형이가능하다. '?' 문자와 super 키워드 <? super S> - S 형의슈퍼클래스형으로제한한다. '?' 문자와 extends 키워드 <? extends S> - S 형의서브클래스형으로제한한다. kkman@sangji.ac.kr 20
프로그램요소에다양한종류의정보를부여하는것 프로그램요소 클래스 필드 메소드 시스템정의어노테이션과사용자정의어노테이션으로구분 추가된정보는실행시간에자바의리플렉션 (reflection) 을통해다양한용도로사용 JDK에서어노테이션을처리하기위한도구 - APT(Application Processing Tool) kkman@sangji.ac.kr 21
어노테이션사용방법 프로그래밍단위의수정자가명시되는위치에표기 형식 '@'(at) 기호다음에어노테이션이름을명시 추가정보는 '(' 와 ')' 사이에 '', 로구분하여기술 @AnnotationTypeName @AnnotationTypeName ( elementvalue ) @AnnotationTypeName ( element = value, element = value,... ) kkman@sangji.ac.kr 22
어노테이션이갖는추가정보의원소개수에따른구분 마커어노테이션 (marker annotation) ti 이름만있는어노테이션 @AnnotationTypeName 단원소어노테이션 (single-element annotation) 하나의원소만을가지고있는어노테이션 @AnnotationTypeName(elementValue) '{' 와 '' 사이에 '' ',' 로구분하여원소에여러개의값을줄수있음 일반어노테이션 (normal annotation) 여러개의원소를갖는어노테이션 @AnnotationName(element=value, element=value,...) kkman@sangji.ac.kr 23
자바언어에서제공하는어노테이션으로자바언어와실행환경에서사용함 Override Deprecated SuppressWarnings Target Retention kkman@sangji.ac.kr 24
서브클래스에서슈퍼클래스의메소드를재정의하는것을명시적으로지정하기위해서사용 Override 어노테이션이명시된메소드가슈퍼클래스의메소드를재정의하지못하면컴파일에러가발생함 kkman@sangji.ac.kr 25
특정클래스나인터페이스, 메소드, 필드등이앞으로사라질수있다는것을경고하기위해서사용 Deprecated 어노테이션이명시된프로그램요소를참조하면, 컴파일러는경고메시지를출력함 kkman@sangji.ac.kr 26
Deprecated 어노테이션의사용예 [ 예제 10.10 - DeprecatedAnnotation.java] class OldAndNewClass { /** *@d @deprecated dreplaced oldmethod d by newmehotd. */ @Deprecated public static void oldmethod() { System.out.println("In the Old Method..."); public static void newmethod() { System.out.println("In the New Method..."); public class DeprecatedAnnotation { public static void main(string [] args) { OldAndNewClass o = new OldAndNewClass(); o.newmethod(); o.oldmethod(); kkman@sangji.ac.kr 27
컴파일결과 : Note: DeprecatedAnnotation.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. 컴파일옵션 (-Xlint:deprecation) 을추가한후결과 : DeprecatedAnnotation.java:17: warning: [deprecation] oldmethod() in OldAndNewClass has been deprecated o.oldmethod(); ^ 1 warning 실행결과 : In the New Method... In the Old Method... kkman@sangji.ac.kr 28
컴파일러가발생시키는특정경고메시지를억제하기위해사용 unchecked 제네릭형과로우형을동시에허용함에따른경고의억제 deprecation 데프리케이티드 (deprecated) 된요소의사용시발생하는경고의억제 @SuppressWarnings("unchecked") @SuppressWarnings("deprecation") @SuppressWarnings({"unchecked", "deprecation") kkman@sangji.ac.kr 29
어노테이션을정의시어노테이션이사용가능한프로그램요소를결정하기위해사용 ElementType 의상수로프로그램요소를나타냄 ElementType 상수 ANNOTATION_TYPE CONSTRUCTOR FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE 의미어노테이션형생성자열거상수를포함한필드지역변수메소드패키지매개변수클래스, 인터페이스 ( 어노테이션형포함 ), 열거형 kkman@sangji.ac.kr 30
어노테이션정보의유지범위를설정하기위해사용 RetentionPolicy ti 의상수로나타냄 RetentionPolicy 상수 CLASS RUNTIME SOURCE 의미어노테이션정보를컴파일러는클래스파일에저장하지만가상기계는읽지않음. 어노테이션정보를컴파일러는클래스파일에저장하고가상기계는저장된정보를읽음. 어노테이션정보를클래스파일에저장되지않고, 소스를처리하는도구에서만사용. kkman@sangji.ac.kr 31
프로그래머가정의하는어노테이션 어노테이션형을정의한후사용 이름앞에 '@' 문자가오는것외에는기본적으로인터페이스를선언하는것과동일사용방법 : 시스템정의어노테이션과동일 어노테이션형정의 [modifiers] @interface AnnotationTypeName ti { // Declaration of Annotation elements kkman@sangji.ac.kr 32
어노테이션원소의형으로사용가능한자료형 기본형, 스트링, 클래스형, 열거형, 어노테이션형 사용가능한형의배열형 기본값설정 default "[default_value]" 어노테이션형정의의예 public @interface ProgramTask { int id(); String programmer() default "[unassigned] "; String date() default "[unimplemented] "; kkman@sangji.ac.kr 33