SlideShare uma empresa Scribd logo
1 de 68
Baixar para ler offline
Reflection
+ Annotation
2013. 7. 23
이준영
13년 7월 23일 화요일
Class?
• 클래스를 구성하는 것들
• Fields,
• Methods,
• Constructors
13년 7월 23일 화요일
Class details
Field
Constructor
Method
13년 7월 23일 화요일
이클립스는
어떻게
Contents Assist(Ctrl + Space)를
지원할까?
13년 7월 23일 화요일
이클립스는
클래스가 어떻게 생겨먹었는지 알고 있다.
13년 7월 23일 화요일
Class 클래스
• 어떤 클래스의 모양(구성)을 알고 있는 클래스
• Fields,
• Methods,
• Constructors
• 상속 받은 것,
정의한 것,
인터페이스 등
13년 7월 23일 화요일
예제 자바 프로젝트 생성
13년 7월 23일 화요일
Class 클래스로 클래스 살펴보기
• 파헤쳐볼 WishItem 클래스 작성
13년 7월 23일 화요일
Class 클래스로 클래스 살펴보기
• 파헤쳐볼 WishItem 클래스 작성
13년 7월 23일 화요일
Class 클래스로 클래스 살펴보기
• 파헤쳐볼 WishItem 클래스 작성
public class WishItem implements Serializable{
	 private int id;
	 private String name;
	 private String createdTime;
	
	 public WishItem(String name, String createdTime) {
	 	 this(-1, name, createdTime);
	 }
	
	 public WishItem(int id, String name, String createdTime) {
	 	 this.id = id;
	 	 this.name = name;
	 	 this.createdTime = createdTime;
	 }
	
	 public int getId() {
	 	 return id;
	 }
	 public void setId(int id) {
	 	 this.id = id;
	 }
	 public String getName() {
	 	 return name;
	 }
	 public void setName(String name) {13년 7월 23일 화요일
Class 클래스로 클래스 살펴보기
• 파헤쳐볼 WishItem 클래스 작성
	 	 this.name = name;
	 	 this.createdTime = createdTime;
	 }
	
	 public int getId() {
	 	 return id;
	 }
	 public void setId(int id) {
	 	 this.id = id;
	 }
	 public String getName() {
	 	 return name;
	 }
	 public void setName(String name) {
	 	 this.name = name;
	 }
	 public String getCreatedTime() {
	 	 return createdTime;
	 }
	 public void setCreatedTime(String createdTime) {
	 	 this.createdTime = createdTime;
	 }
}
13년 7월 23일 화요일
우린 왜 IDE를 쓸까?
잠깐, 다른 이야기
13년 7월 23일 화요일
우린 왜 IDE를 쓸까?
좀 더 편하고 빠르게 개발하기 위해서
잠깐, 다른 이야기
13년 7월 23일 화요일
Eclipse의 소스 생성 기능
13년 7월 23일 화요일
WishItem 클래스 정보 읽어보기
• Main 메서드 작성
main 쓰고 Ctrl + Space bar
• 클래스의 Class 클래스 인스턴스를 가져오기
Class<WishItem> clazz = WishItem.class
Class<? extends WishItem> clazz =
obj.getClass()
13년 7월 23일 화요일
.class vs .getClass()
• .class는 타입 그대로의 클래스를 가져옴
• .getClass()는 인스턴스의 실제 타입의 클래스
를 가져옴
Animal
Dog
상속
Animal a = new Animal();
Animal d = new Dog();
d 의 클래스 정보를 얻기 위해서는
Animal.class가 맞을까, d.getClass()가 맞을까?
13년 7월 23일 화요일
clazz.
• getDeclaredField(String name) - Field
• getDeclaredFields() - Fields[]
• getDeclaredMethod(String name) - Method
• getDeclaredMethods() - Method[]
• getDeclaredConstructor(Class<?
>...paramTypes)
• getDeclaredConstructors() - Constructor
13년 7월 23일 화요일
clazz. ...
13년 7월 23일 화요일
clazz. ...
13년 7월 23일 화요일
clazz. ...
공부 많이 해야겠죠?
그렇다고 외우진 마세요.
그런게 있었다는 것만 기억!
13년 7월 23일 화요일
하나씩 해 봅시다.
• Field 가져오기
	 	 WishItem wi = new WishItem(0, "2013.7.23", "세상의 모든 지식");
	 	 Class<? extends WishItem> clazz = wi.getClass();
	 	
	 	 try {
	 	 	 Field idField = clazz.getDeclaredField("id");
	 	 	
	 	 	 // 필드의 이름 출력
	 	 	 System.out.println(idField.getName());
	 	 } catch (NoSuchFieldException e) {
	 	 	 // 찾는 이름의 필드가 없을 때
	 	 	 e.printStackTrace();
	 	 } catch (SecurityException e) {
	 	 	 // 접근 제한 발생할 때
	 	 	 e.printStackTrace();
	 	 }
13년 7월 23일 화요일
• Field의 값 보기, 바꾸기
	 	 try {
	 	 	 Field idField = clazz.getDeclaredField("id");
	 	 	
	 	 	 // 필드의 이름 출력
	 	 	 System.out.println(idField.getName());
	 	 	
	 	 	 // 접근이 가능하도록 설정
	 	 	 idField.setAccessible(true);
	 	 	 // 필드 값 가져오기
	 	 	 System.out.println(idField.get(wi));
	 	 	
	 	 	 // idField의 값을 15로 변경
	 	 	 idField.set(wi, 15);
	 	 	
	 	 	 // WishItem 객체에 실제로 바뀌었는지 확인
	 	 	 System.out.println(wi.id);
	 	 	
	 	 	 // 다시 접근이 불가능하도록 설정
	 	 	 idField.setAccessible(false);
...
13년 7월 23일 화요일
• Field의 값 보기, 바꾸기
	 	 try {
	 	 	 Field idField = clazz.getDeclaredField("id");
	 	 	
	 	 	 // 필드의 이름 출력
	 	 	 System.out.println(idField.getName());
	 	 	
	 	 	 // 접근이 가능하도록 설정
	 	 	 idField.setAccessible(true);
	 	 	 // 필드 값 가져오기
	 	 	 System.out.println(idField.get(wi));
	 	 	
	 	 	 // idField의 값을 15로 변경
	 	 	 idField.set(wi, 15);
	 	 	
	 	 	 // WishItem 객체에 실제로 바뀌었는지 확인
	 	 	 System.out.println(wi.id);
	 	 	
	 	 	 // 다시 접근이 불가능하도록 설정
	 	 	 idField.setAccessible(false);
...
13년 7월 23일 화요일
• Field의 값 보기, 바꾸기
	 	 try {
	 	 	 Field idField = clazz.getDeclaredField("id");
	 	 	
	 	 	 // 필드의 이름 출력
	 	 	 System.out.println(idField.getName());
	 	 	
	 	 	 // 접근이 가능하도록 설정
	 	 	 idField.setAccessible(true);
	 	 	 // 필드 값 가져오기
	 	 	 System.out.println(idField.get(wi));
	 	 	
	 	 	 // idField의 값을 15로 변경
	 	 	 idField.set(wi, 15);
	 	 	
	 	 	 // WishItem 객체에 실제로 바뀌었는지 확인
	 	 	 System.out.println(wi.id);
	 	 	
	 	 	 // 다시 접근이 불가능하도록 설정
	 	 	 idField.setAccessible(false);
...
13년 7월 23일 화요일
• 모든 Field 가져오기
	 	 Field[] fields = clazz.getDeclaredFields();
	 	
	 	 for(Field field : fields) {
	 	 	 System.out.println(field.getName());
	 	 }
Field의 배열 형태로 반환
13년 7월 23일 화요일
• 특정 Method 가져오기
getName 메서드 살짝 수정
	 public String getName() {
	 	 System.out.println("위시 아이템 이름은 " + name);
	 	 return name;
	 }
try {
	 	 	 // 특정 Method 가져오기
	 	 	 Method getNameMethod = clazz.getDeclaredMethod("getName");
	 	 	
	 	 	 // 메서드의 이름 확인
	 	 	 System.out.println(getNameMethod.getName());
	 	 } catch (NoSuchMethodException e) {
	 	 	 // 그런 메서드가 없음!
	 	 	 e.printStackTrace();
	 	 } catch (SecurityException e) {
	 	 	 // 시큐리티! 시큐리티!
	 	 	 e.printStackTrace();
	 	 }
}
13년 7월 23일 화요일
• 메서드 실행하기
• 실행 결과
	 	 	 // 메서드 실행하기
	 	 	 String name = (String)getNameMethod.invoke(wi);
	 	 	
	 	 	 // 가져온 값 확인
	 	 	 System.out.println("가져온 값 : " + name);
위시 아이템 이름은 세상의 모든 지식
가져온 값 : 세상의 모든 지식
13년 7월 23일 화요일
Q : 모든 메서드를 가져와서 이름 출력해 보기
13년 7월 23일 화요일
• Class 클래스를 이용해 인스턴스 만들기
	 	 try {
	 	 	 WishItem item = clazz.newInstance();
	 	 } catch (InstantiationException e) {
	 	 	 e.printStackTrace();
	 	 } catch (IllegalAccessException e) {
	 	 	 e.printStackTrace();
	 	 }
13년 7월 23일 화요일
• Class 클래스를 이용해 인스턴스 만들기
	 	 try {
	 	 	 WishItem item = clazz.newInstance();
	 	 } catch (InstantiationException e) {
	 	 	 e.printStackTrace();
	 	 } catch (IllegalAccessException e) {
	 	 	 e.printStackTrace();
	 	 }
newInstance 메서드는 해당 클래스가 매개변수가 없는
기본 생성자를 가지고 있어야 사용 가능
13년 7월 23일 화요일
기본 생성자를 만들거나
혹은
Constructor를 이용
13년 7월 23일 화요일
• Constructor를 이용해서 인스턴스 만들기
try {
	 // 생성자 가져오기
	 Constructor cons = clazz.getDeclaredConstructor(int.class, String.class, String.class);
	
	 // 생성자를 통해서 인스턴스 생성
	 WishItem item = (WishItem) cons.newInstance(4, "2013. 7. 23", "갤럭시 S4");
	
	 // 실제로 잘 생성되었는지 값 확인
	 System.out.println(item.getName());
} catch (Exception e) { } // 예외는 길이 상 생략..
13년 7월 23일 화요일
Reflection?
• 객체를 통해 클래스의 정보를 분석해 내는 프
로그램 기법
• 타입은 알고 있지만 형변환을 할 수 없는 상태
에서 메서드를 호출
13년 7월 23일 화요일
Reflection?
• 객체를 통해 클래스의 정보를 분석해 내는 프
로그램 기법
• 타입은 알고 있지만 형변환을 할 수 없는 상태
에서 메서드를 호출
앞에서 살펴본 Class 클래스 가지고 놀기
13년 7월 23일 화요일
Annotation
• 사전적 정의 : 주석
• Meta Data : 데이터에 대한 데이터
• 어노테이션은 @으로 표현
13년 7월 23일 화요일
Annotation
• 사전적 정의 : 주석
• Meta Data : 데이터에 대한 데이터
• 어노테이션은 @으로 표현
@Override
@Deprecated
@SuppressWarnings
최소한 @Override는 본적 있죠?
13년 7월 23일 화요일
일단 만들어 봅시다.
• File >> New
13년 7월 23일 화요일
• 그럼 이런 파일이 생성
• WishItem 클래스의 name 필드에 붙여보기
public @interface FirstAnno {
}
@FirstAnno
private String name;
짠!
13년 7월 23일 화요일
• Annotation에 값 담기
• WishItem으로 돌아가보면..
• 그릇이 생겼으니 담아줘야.
public @interface FirstAnno {
	 public int value();
}
@FirstAnno
private String name;
@FirstAnno(27)
private String name;
13년 7월 23일 화요일
• 또 다른 값 담아보기
• 다시 WishItem 클래스로..
public @interface FirstAnno {
	 public int value();
	
	 public String weekday();
}
@FirstAnno(value=27, weekday="화요일")
private String name;
13년 7월 23일 화요일
처음에는 value 라고 적어주지 않았었는데..?
@FirstAnno(27)
private String name;
13년 7월 23일 화요일
value는 어노테이션의 기본값을 담는 이름
>> 이름 없이도 값을 담는 어노테이션 변수
13년 7월 23일 화요일
• 어노테이션 변수에 기본값 지정
public @interface FirstAnno {
	 public int value() default 0;
	
	 public String weekday();
}
@FirstAnno(weekday="화요일")
private String name;
13년 7월 23일 화요일
어노테이션의 어노테이션
13년 7월 23일 화요일
• 이건 또 무슨 Class의 클래스 같은 소리?
어노테이션의 어노테이션
13년 7월 23일 화요일
• 이건 또 무슨 Class의 클래스 같은 소리?
• 어노테이션 인터페이스 정의에 붙이는
어노테이션을 말함
어노테이션의 어노테이션
13년 7월 23일 화요일
• 이건 또 무슨 Class의 클래스 같은 소리?
• 어노테이션 인터페이스 정의에 붙이는
어노테이션을 말함
• Meta 어노테이션이라고 함
어노테이션의 어노테이션
13년 7월 23일 화요일
• 이건 또 무슨 Class의 클래스 같은 소리?
• 어노테이션 인터페이스 정의에 붙이는
어노테이션을 말함
• Meta 어노테이션이라고 함
• @Target,
@Retention,
@Documented,
@Inherited 하나씩 알아봅시다.
어노테이션의 어노테이션
13년 7월 23일 화요일
@Target
• 어노테이션이 적용될 타입을 지정
@Target({ElementType.TYPE,
ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.ANNOTATION_TYPE})
public @interface FirstAnno {
	 public int value() default 0;
	
	 public String weekday();
}
13년 7월 23일 화요일
• ElementType.TYPE
: 클래스에 적용하는 어노테이션으로 설정
• ElementType.METHOD
: 메서드에 적용하는 어노테이션으로 설정
• ElementType.CONSTRUCTOR
:생성자에 적용하는 어노테이션으로 설정
• ElementType.ANNOTATION_TYPE
:어노테이션에 적용하는 어노테이션으로 설정
13년 7월 23일 화요일
• ElementType.FIELD
: 필드에 적용하는 어노테이션으로 설정
• ElementType.PARAMETER
: 매개변수에 적용하는 어노테이션으로 설정
• ElementType.LOCAL_VARIABLE
:지역변수에 적용하는 어노테이션으로 설정
• ElementType.PACKAGE
:패키지에 적용하는 어노테이션으로 설정
13년 7월 23일 화요일
• 필드에만 적용할 어노테이션으로 지정
@Target(ElementType.FIELD)
public @interface FirstAnno {
	 public int value() default 0;
	
	 public String weekday();
}
13년 7월 23일 화요일
• 어노테이션이 언제까지 유효할 지 설정
• @Retention(RetentionPolicy. ?)
@Retention
Source
Code
Compile Runtime
13년 7월 23일 화요일
• RetentionPolicy.SOURCE
: 소스코드 상에서만 유효함
• RetentionPolicy.COMPILE
: 컴파일 단계까지 유효함
• RetentionPolicy.RUNTIME
:프로그램이 실행 중(런타임)일 때도 유효함
13년 7월 23일 화요일
• JavaDoc으로 출력 시 어노테이션 정보를 출력
할 것인지를 설정
• @Documented가 적용되어있는 어노테이션
은 Java Doc에서도 표현됨
• 없으면 해당 어노테이션은 표현되지 않음
@Documented
13년 7월 23일 화요일
@Inherited
• 하위(자식) 클래스에서 어노테이션을 유지할
것인지를 결정
• @Inherited가 적용되어 있는 경우 하위 클래
스에서도 동일하게 어노테이션이 적용됨
• @Retention(RetentionPolicy.RUNTIME)이
함께 적용되어야 의미가 있음
13년 7월 23일 화요일
안드로이드 스터디 하다가
왜?
Reflection과 Annotation을?
13년 7월 23일 화요일
btnAdd = (Button)findViewById(R.id.wl_btnAddWishItem);
etItemName = (EditText)findViewById(R.id.wl_etWishItemName);
lvItems = (ListView)findViewById(R.id.wl_lvItems);
@ViewById
private Button btnAdd;
@ViewById
private EditText etItemName;
@ViewById
private ListView lvItems;
13년 7월 23일 화요일
룰을 정하자
• @ViewById 에 값을 넘겨주지 않으면
필드의 이름을 ID로 간주하자
• @ViewById(R.id.xxx) 처럼
ID를 직접 넘겨줄 수 있다.
• So Simple!
그렇지만 구현은.. @(#@*!&%
13년 7월 23일 화요일
@ViewById 구현
13년 7월 23일 화요일
package yapp.aa.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* View 클래스의 findViewById 메서드를 대체하기 위한 어노테이션 <p>
*
* case 1.value 값을 전달받는 경우 그 값을 ID로 사용 </br>
* case 2.value 값을 전달받지 않는 경우 어노테이션이 적용된 필드의 이름을 ID로 사용</br>
* @author 이준영
*
*/
@Target(ElementType.FIELD) // 멤버 변수(필드)에만 적용하도록 함
@Retention(RetentionPolicy.RUNTIME) // 런타임에 유효하도록 함
public @interface ViewById {
	 /**
	 * 뷰의 ID 저장
	 * @return 뷰의 ID
	 */
	 public int value() default -1;
}
13년 7월 23일 화요일
package yapp.aa.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById {
	 public int value() default -1;
}
주석 빼면? 사실 몇 줄 안되는 어노테이션
13년 7월 23일 화요일
ViewByIdResolver Class
리플렉션을 통해 Activity의 필드 중
@ViewById 어노테이션이 적용된 필드에
뷰를 찾아 설정해주는 역할을 수행
13년 7월 23일 화요일
어떻게 해야할까?
• Reflection을 통해 액티비티의 필드를 가져옴
getDeclaredFields()
• 가져온 필드에 적용된 어노테이션을 가져옴
getAnnotation(ViewById.class)
• 어노테이션이 적용되었다면 값을 가져옴
null인 경우는 어노테이션이 적용되지 않은 필드
• value가 -1인지, 지정된 값인지에 따른 처리
• 액티비티에서 뷰를 찾아서 필드에 값을 설정
13년 7월 23일 화요일
이런 모양으로 시작해봅시다
public class ViewByIdResolver{
	 public static void resolve(Activity activity) {
	 	
	 }
}
13년 7월 23일 화요일
ㄱㄱ
13년 7월 23일 화요일
더 많은 것들을 할 수 있지 않을까?
13년 7월 23일 화요일
findViewById 말고?
• setOnClickListener?
• 여기서 숙제 @Click 만들어보기
(사실 검색해도 나오긴 합니다 :D )
• 요점은 고민해보기
13년 7월 23일 화요일

Mais conteúdo relacionado

Semelhante a Yapp a.a study 2 reflection+annotation

Java programming pdf
Java programming pdfJava programming pdf
Java programming pdfJi Hoon Lee
 
Objective-C Runtime Programming Guide
Objective-C Runtime Programming GuideObjective-C Runtime Programming Guide
Objective-C Runtime Programming GuideSung-Kwan Kim
 
게임프로그래밍입문 7
게임프로그래밍입문 7게임프로그래밍입문 7
게임프로그래밍입문 7Yeonah Ki
 
Java, android 스터티2
Java, android 스터티2Java, android 스터티2
Java, android 스터티2Heejun Kim
 
파이썬 모듈 패키지
파이썬 모듈 패키지파이썬 모듈 패키지
파이썬 모듈 패키지SeongHyun Ahn
 
[C++ lab] 3. c++ 프로그래밍
[C++ lab] 3. c++ 프로그래밍[C++ lab] 3. c++ 프로그래밍
[C++ lab] 3. c++ 프로그래밍MinGeun Park
 
Ksug2015 - JPA1, JPA 소개
Ksug2015 - JPA1, JPA 소개Ksug2015 - JPA1, JPA 소개
Ksug2015 - JPA1, JPA 소개Younghan Kim
 
Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)승욱 정
 
C++ Advanced 강의 1주차
C++ Advanced 강의 1주차C++ Advanced 강의 1주차
C++ Advanced 강의 1주차HyunJoon Park
 
Yapp a.a 2 2 sugar orm
Yapp a.a 2 2 sugar ormYapp a.a 2 2 sugar orm
Yapp a.a 2 2 sugar ormJunyoung Lee
 
[162] jpa와 모던 자바 데이터 저장 기술
[162] jpa와 모던 자바 데이터 저장 기술[162] jpa와 모던 자바 데이터 저장 기술
[162] jpa와 모던 자바 데이터 저장 기술NAVER D2
 

Semelhante a Yapp a.a study 2 reflection+annotation (13)

Java programming pdf
Java programming pdfJava programming pdf
Java programming pdf
 
Clean code Chapter.2
Clean code Chapter.2Clean code Chapter.2
Clean code Chapter.2
 
Objective-C Runtime Programming Guide
Objective-C Runtime Programming GuideObjective-C Runtime Programming Guide
Objective-C Runtime Programming Guide
 
Swt J Face 2/3
Swt J Face 2/3Swt J Face 2/3
Swt J Face 2/3
 
게임프로그래밍입문 7
게임프로그래밍입문 7게임프로그래밍입문 7
게임프로그래밍입문 7
 
Java, android 스터티2
Java, android 스터티2Java, android 스터티2
Java, android 스터티2
 
파이썬 모듈 패키지
파이썬 모듈 패키지파이썬 모듈 패키지
파이썬 모듈 패키지
 
[C++ lab] 3. c++ 프로그래밍
[C++ lab] 3. c++ 프로그래밍[C++ lab] 3. c++ 프로그래밍
[C++ lab] 3. c++ 프로그래밍
 
Ksug2015 - JPA1, JPA 소개
Ksug2015 - JPA1, JPA 소개Ksug2015 - JPA1, JPA 소개
Ksug2015 - JPA1, JPA 소개
 
Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)Swift3 : class and struct(+property+method)
Swift3 : class and struct(+property+method)
 
C++ Advanced 강의 1주차
C++ Advanced 강의 1주차C++ Advanced 강의 1주차
C++ Advanced 강의 1주차
 
Yapp a.a 2 2 sugar orm
Yapp a.a 2 2 sugar ormYapp a.a 2 2 sugar orm
Yapp a.a 2 2 sugar orm
 
[162] jpa와 모던 자바 데이터 저장 기술
[162] jpa와 모던 자바 데이터 저장 기술[162] jpa와 모던 자바 데이터 저장 기술
[162] jpa와 모던 자바 데이터 저장 기술
 

Mais de Junyoung Lee

Git 더하기 GitHub(Git클라이언트 활용) / Getting started with git+github
Git 더하기 GitHub(Git클라이언트 활용) / Getting started with git+githubGit 더하기 GitHub(Git클라이언트 활용) / Getting started with git+github
Git 더하기 GitHub(Git클라이언트 활용) / Getting started with git+githubJunyoung Lee
 
강의 전 준비(GitHub가입, git 클라이언트 설치)
강의 전 준비(GitHub가입, git 클라이언트 설치)강의 전 준비(GitHub가입, git 클라이언트 설치)
강의 전 준비(GitHub가입, git 클라이언트 설치)Junyoung Lee
 
Slideshare font test
Slideshare font testSlideshare font test
Slideshare font testJunyoung Lee
 
Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)Junyoung Lee
 
Git 더하기 GitHub 강의 전 준비
Git 더하기 GitHub 강의 전 준비Git 더하기 GitHub 강의 전 준비
Git 더하기 GitHub 강의 전 준비Junyoung Lee
 
웹 IDE 비교
웹 IDE 비교웹 IDE 비교
웹 IDE 비교Junyoung Lee
 
팀프로젝트 활짝 피우기
팀프로젝트 활짝 피우기팀프로젝트 활짝 피우기
팀프로젝트 활짝 피우기Junyoung Lee
 
Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용
Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용
Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용Junyoung Lee
 
Yapp a.a 2 2 android annotations
Yapp a.a 2 2 android annotationsYapp a.a 2 2 android annotations
Yapp a.a 2 2 android annotationsJunyoung Lee
 
[Yapp aa] 스터디 과제
[Yapp aa] 스터디 과제[Yapp aa] 스터디 과제
[Yapp aa] 스터디 과제Junyoung Lee
 

Mais de Junyoung Lee (14)

Git 더하기 GitHub(Git클라이언트 활용) / Getting started with git+github
Git 더하기 GitHub(Git클라이언트 활용) / Getting started with git+githubGit 더하기 GitHub(Git클라이언트 활용) / Getting started with git+github
Git 더하기 GitHub(Git클라이언트 활용) / Getting started with git+github
 
강의 전 준비(GitHub가입, git 클라이언트 설치)
강의 전 준비(GitHub가입, git 클라이언트 설치)강의 전 준비(GitHub가입, git 클라이언트 설치)
강의 전 준비(GitHub가입, git 클라이언트 설치)
 
Slideshare font test
Slideshare font testSlideshare font test
Slideshare font test
 
Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)
 
Git 더하기 GitHub 강의 전 준비
Git 더하기 GitHub 강의 전 준비Git 더하기 GitHub 강의 전 준비
Git 더하기 GitHub 강의 전 준비
 
웹 IDE 비교
웹 IDE 비교웹 IDE 비교
웹 IDE 비교
 
팀프로젝트 활짝 피우기
팀프로젝트 활짝 피우기팀프로젝트 활짝 피우기
팀프로젝트 활짝 피우기
 
Tdd with JUnit 1
Tdd with JUnit 1Tdd with JUnit 1
Tdd with JUnit 1
 
TDD with JUnit 2
TDD with JUnit 2TDD with JUnit 2
TDD with JUnit 2
 
Dropbox 꿀팁
Dropbox 꿀팁Dropbox 꿀팁
Dropbox 꿀팁
 
Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용
Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용
Yapp Advanced Android 3주차 - BaaS.io 이해 및 사용
 
Yapp a.a 2 2 android annotations
Yapp a.a 2 2 android annotationsYapp a.a 2 2 android annotations
Yapp a.a 2 2 android annotations
 
[Yapp aa] 스터디 과제
[Yapp aa] 스터디 과제[Yapp aa] 스터디 과제
[Yapp aa] 스터디 과제
 
Git
GitGit
Git
 

Yapp a.a study 2 reflection+annotation

  • 1. Reflection + Annotation 2013. 7. 23 이준영 13년 7월 23일 화요일
  • 2. Class? • 클래스를 구성하는 것들 • Fields, • Methods, • Constructors 13년 7월 23일 화요일
  • 4. 이클립스는 어떻게 Contents Assist(Ctrl + Space)를 지원할까? 13년 7월 23일 화요일
  • 5. 이클립스는 클래스가 어떻게 생겨먹었는지 알고 있다. 13년 7월 23일 화요일
  • 6. Class 클래스 • 어떤 클래스의 모양(구성)을 알고 있는 클래스 • Fields, • Methods, • Constructors • 상속 받은 것, 정의한 것, 인터페이스 등 13년 7월 23일 화요일
  • 7. 예제 자바 프로젝트 생성 13년 7월 23일 화요일
  • 8. Class 클래스로 클래스 살펴보기 • 파헤쳐볼 WishItem 클래스 작성 13년 7월 23일 화요일
  • 9. Class 클래스로 클래스 살펴보기 • 파헤쳐볼 WishItem 클래스 작성 13년 7월 23일 화요일
  • 10. Class 클래스로 클래스 살펴보기 • 파헤쳐볼 WishItem 클래스 작성 public class WishItem implements Serializable{ private int id; private String name; private String createdTime; public WishItem(String name, String createdTime) { this(-1, name, createdTime); } public WishItem(int id, String name, String createdTime) { this.id = id; this.name = name; this.createdTime = createdTime; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) {13년 7월 23일 화요일
  • 11. Class 클래스로 클래스 살펴보기 • 파헤쳐볼 WishItem 클래스 작성 this.name = name; this.createdTime = createdTime; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCreatedTime() { return createdTime; } public void setCreatedTime(String createdTime) { this.createdTime = createdTime; } } 13년 7월 23일 화요일
  • 12. 우린 왜 IDE를 쓸까? 잠깐, 다른 이야기 13년 7월 23일 화요일
  • 13. 우린 왜 IDE를 쓸까? 좀 더 편하고 빠르게 개발하기 위해서 잠깐, 다른 이야기 13년 7월 23일 화요일
  • 14. Eclipse의 소스 생성 기능 13년 7월 23일 화요일
  • 15. WishItem 클래스 정보 읽어보기 • Main 메서드 작성 main 쓰고 Ctrl + Space bar • 클래스의 Class 클래스 인스턴스를 가져오기 Class<WishItem> clazz = WishItem.class Class<? extends WishItem> clazz = obj.getClass() 13년 7월 23일 화요일
  • 16. .class vs .getClass() • .class는 타입 그대로의 클래스를 가져옴 • .getClass()는 인스턴스의 실제 타입의 클래스 를 가져옴 Animal Dog 상속 Animal a = new Animal(); Animal d = new Dog(); d 의 클래스 정보를 얻기 위해서는 Animal.class가 맞을까, d.getClass()가 맞을까? 13년 7월 23일 화요일
  • 17. clazz. • getDeclaredField(String name) - Field • getDeclaredFields() - Fields[] • getDeclaredMethod(String name) - Method • getDeclaredMethods() - Method[] • getDeclaredConstructor(Class<? >...paramTypes) • getDeclaredConstructors() - Constructor 13년 7월 23일 화요일
  • 18. clazz. ... 13년 7월 23일 화요일
  • 19. clazz. ... 13년 7월 23일 화요일
  • 20. clazz. ... 공부 많이 해야겠죠? 그렇다고 외우진 마세요. 그런게 있었다는 것만 기억! 13년 7월 23일 화요일
  • 21. 하나씩 해 봅시다. • Field 가져오기 WishItem wi = new WishItem(0, "2013.7.23", "세상의 모든 지식"); Class<? extends WishItem> clazz = wi.getClass(); try { Field idField = clazz.getDeclaredField("id"); // 필드의 이름 출력 System.out.println(idField.getName()); } catch (NoSuchFieldException e) { // 찾는 이름의 필드가 없을 때 e.printStackTrace(); } catch (SecurityException e) { // 접근 제한 발생할 때 e.printStackTrace(); } 13년 7월 23일 화요일
  • 22. • Field의 값 보기, 바꾸기 try { Field idField = clazz.getDeclaredField("id"); // 필드의 이름 출력 System.out.println(idField.getName()); // 접근이 가능하도록 설정 idField.setAccessible(true); // 필드 값 가져오기 System.out.println(idField.get(wi)); // idField의 값을 15로 변경 idField.set(wi, 15); // WishItem 객체에 실제로 바뀌었는지 확인 System.out.println(wi.id); // 다시 접근이 불가능하도록 설정 idField.setAccessible(false); ... 13년 7월 23일 화요일
  • 23. • Field의 값 보기, 바꾸기 try { Field idField = clazz.getDeclaredField("id"); // 필드의 이름 출력 System.out.println(idField.getName()); // 접근이 가능하도록 설정 idField.setAccessible(true); // 필드 값 가져오기 System.out.println(idField.get(wi)); // idField의 값을 15로 변경 idField.set(wi, 15); // WishItem 객체에 실제로 바뀌었는지 확인 System.out.println(wi.id); // 다시 접근이 불가능하도록 설정 idField.setAccessible(false); ... 13년 7월 23일 화요일
  • 24. • Field의 값 보기, 바꾸기 try { Field idField = clazz.getDeclaredField("id"); // 필드의 이름 출력 System.out.println(idField.getName()); // 접근이 가능하도록 설정 idField.setAccessible(true); // 필드 값 가져오기 System.out.println(idField.get(wi)); // idField의 값을 15로 변경 idField.set(wi, 15); // WishItem 객체에 실제로 바뀌었는지 확인 System.out.println(wi.id); // 다시 접근이 불가능하도록 설정 idField.setAccessible(false); ... 13년 7월 23일 화요일
  • 25. • 모든 Field 가져오기 Field[] fields = clazz.getDeclaredFields(); for(Field field : fields) { System.out.println(field.getName()); } Field의 배열 형태로 반환 13년 7월 23일 화요일
  • 26. • 특정 Method 가져오기 getName 메서드 살짝 수정 public String getName() { System.out.println("위시 아이템 이름은 " + name); return name; } try { // 특정 Method 가져오기 Method getNameMethod = clazz.getDeclaredMethod("getName"); // 메서드의 이름 확인 System.out.println(getNameMethod.getName()); } catch (NoSuchMethodException e) { // 그런 메서드가 없음! e.printStackTrace(); } catch (SecurityException e) { // 시큐리티! 시큐리티! e.printStackTrace(); } } 13년 7월 23일 화요일
  • 27. • 메서드 실행하기 • 실행 결과 // 메서드 실행하기 String name = (String)getNameMethod.invoke(wi); // 가져온 값 확인 System.out.println("가져온 값 : " + name); 위시 아이템 이름은 세상의 모든 지식 가져온 값 : 세상의 모든 지식 13년 7월 23일 화요일
  • 28. Q : 모든 메서드를 가져와서 이름 출력해 보기 13년 7월 23일 화요일
  • 29. • Class 클래스를 이용해 인스턴스 만들기 try { WishItem item = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } 13년 7월 23일 화요일
  • 30. • Class 클래스를 이용해 인스턴스 만들기 try { WishItem item = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } newInstance 메서드는 해당 클래스가 매개변수가 없는 기본 생성자를 가지고 있어야 사용 가능 13년 7월 23일 화요일
  • 31. 기본 생성자를 만들거나 혹은 Constructor를 이용 13년 7월 23일 화요일
  • 32. • Constructor를 이용해서 인스턴스 만들기 try { // 생성자 가져오기 Constructor cons = clazz.getDeclaredConstructor(int.class, String.class, String.class); // 생성자를 통해서 인스턴스 생성 WishItem item = (WishItem) cons.newInstance(4, "2013. 7. 23", "갤럭시 S4"); // 실제로 잘 생성되었는지 값 확인 System.out.println(item.getName()); } catch (Exception e) { } // 예외는 길이 상 생략.. 13년 7월 23일 화요일
  • 33. Reflection? • 객체를 통해 클래스의 정보를 분석해 내는 프 로그램 기법 • 타입은 알고 있지만 형변환을 할 수 없는 상태 에서 메서드를 호출 13년 7월 23일 화요일
  • 34. Reflection? • 객체를 통해 클래스의 정보를 분석해 내는 프 로그램 기법 • 타입은 알고 있지만 형변환을 할 수 없는 상태 에서 메서드를 호출 앞에서 살펴본 Class 클래스 가지고 놀기 13년 7월 23일 화요일
  • 35. Annotation • 사전적 정의 : 주석 • Meta Data : 데이터에 대한 데이터 • 어노테이션은 @으로 표현 13년 7월 23일 화요일
  • 36. Annotation • 사전적 정의 : 주석 • Meta Data : 데이터에 대한 데이터 • 어노테이션은 @으로 표현 @Override @Deprecated @SuppressWarnings 최소한 @Override는 본적 있죠? 13년 7월 23일 화요일
  • 37. 일단 만들어 봅시다. • File >> New 13년 7월 23일 화요일
  • 38. • 그럼 이런 파일이 생성 • WishItem 클래스의 name 필드에 붙여보기 public @interface FirstAnno { } @FirstAnno private String name; 짠! 13년 7월 23일 화요일
  • 39. • Annotation에 값 담기 • WishItem으로 돌아가보면.. • 그릇이 생겼으니 담아줘야. public @interface FirstAnno { public int value(); } @FirstAnno private String name; @FirstAnno(27) private String name; 13년 7월 23일 화요일
  • 40. • 또 다른 값 담아보기 • 다시 WishItem 클래스로.. public @interface FirstAnno { public int value(); public String weekday(); } @FirstAnno(value=27, weekday="화요일") private String name; 13년 7월 23일 화요일
  • 41. 처음에는 value 라고 적어주지 않았었는데..? @FirstAnno(27) private String name; 13년 7월 23일 화요일
  • 42. value는 어노테이션의 기본값을 담는 이름 >> 이름 없이도 값을 담는 어노테이션 변수 13년 7월 23일 화요일
  • 43. • 어노테이션 변수에 기본값 지정 public @interface FirstAnno { public int value() default 0; public String weekday(); } @FirstAnno(weekday="화요일") private String name; 13년 7월 23일 화요일
  • 45. • 이건 또 무슨 Class의 클래스 같은 소리? 어노테이션의 어노테이션 13년 7월 23일 화요일
  • 46. • 이건 또 무슨 Class의 클래스 같은 소리? • 어노테이션 인터페이스 정의에 붙이는 어노테이션을 말함 어노테이션의 어노테이션 13년 7월 23일 화요일
  • 47. • 이건 또 무슨 Class의 클래스 같은 소리? • 어노테이션 인터페이스 정의에 붙이는 어노테이션을 말함 • Meta 어노테이션이라고 함 어노테이션의 어노테이션 13년 7월 23일 화요일
  • 48. • 이건 또 무슨 Class의 클래스 같은 소리? • 어노테이션 인터페이스 정의에 붙이는 어노테이션을 말함 • Meta 어노테이션이라고 함 • @Target, @Retention, @Documented, @Inherited 하나씩 알아봅시다. 어노테이션의 어노테이션 13년 7월 23일 화요일
  • 49. @Target • 어노테이션이 적용될 타입을 지정 @Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE}) public @interface FirstAnno { public int value() default 0; public String weekday(); } 13년 7월 23일 화요일
  • 50. • ElementType.TYPE : 클래스에 적용하는 어노테이션으로 설정 • ElementType.METHOD : 메서드에 적용하는 어노테이션으로 설정 • ElementType.CONSTRUCTOR :생성자에 적용하는 어노테이션으로 설정 • ElementType.ANNOTATION_TYPE :어노테이션에 적용하는 어노테이션으로 설정 13년 7월 23일 화요일
  • 51. • ElementType.FIELD : 필드에 적용하는 어노테이션으로 설정 • ElementType.PARAMETER : 매개변수에 적용하는 어노테이션으로 설정 • ElementType.LOCAL_VARIABLE :지역변수에 적용하는 어노테이션으로 설정 • ElementType.PACKAGE :패키지에 적용하는 어노테이션으로 설정 13년 7월 23일 화요일
  • 52. • 필드에만 적용할 어노테이션으로 지정 @Target(ElementType.FIELD) public @interface FirstAnno { public int value() default 0; public String weekday(); } 13년 7월 23일 화요일
  • 53. • 어노테이션이 언제까지 유효할 지 설정 • @Retention(RetentionPolicy. ?) @Retention Source Code Compile Runtime 13년 7월 23일 화요일
  • 54. • RetentionPolicy.SOURCE : 소스코드 상에서만 유효함 • RetentionPolicy.COMPILE : 컴파일 단계까지 유효함 • RetentionPolicy.RUNTIME :프로그램이 실행 중(런타임)일 때도 유효함 13년 7월 23일 화요일
  • 55. • JavaDoc으로 출력 시 어노테이션 정보를 출력 할 것인지를 설정 • @Documented가 적용되어있는 어노테이션 은 Java Doc에서도 표현됨 • 없으면 해당 어노테이션은 표현되지 않음 @Documented 13년 7월 23일 화요일
  • 56. @Inherited • 하위(자식) 클래스에서 어노테이션을 유지할 것인지를 결정 • @Inherited가 적용되어 있는 경우 하위 클래 스에서도 동일하게 어노테이션이 적용됨 • @Retention(RetentionPolicy.RUNTIME)이 함께 적용되어야 의미가 있음 13년 7월 23일 화요일
  • 57. 안드로이드 스터디 하다가 왜? Reflection과 Annotation을? 13년 7월 23일 화요일
  • 58. btnAdd = (Button)findViewById(R.id.wl_btnAddWishItem); etItemName = (EditText)findViewById(R.id.wl_etWishItemName); lvItems = (ListView)findViewById(R.id.wl_lvItems); @ViewById private Button btnAdd; @ViewById private EditText etItemName; @ViewById private ListView lvItems; 13년 7월 23일 화요일
  • 59. 룰을 정하자 • @ViewById 에 값을 넘겨주지 않으면 필드의 이름을 ID로 간주하자 • @ViewById(R.id.xxx) 처럼 ID를 직접 넘겨줄 수 있다. • So Simple! 그렇지만 구현은.. @(#@*!&% 13년 7월 23일 화요일
  • 60. @ViewById 구현 13년 7월 23일 화요일
  • 61. package yapp.aa.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * View 클래스의 findViewById 메서드를 대체하기 위한 어노테이션 <p> * * case 1.value 값을 전달받는 경우 그 값을 ID로 사용 </br> * case 2.value 값을 전달받지 않는 경우 어노테이션이 적용된 필드의 이름을 ID로 사용</br> * @author 이준영 * */ @Target(ElementType.FIELD) // 멤버 변수(필드)에만 적용하도록 함 @Retention(RetentionPolicy.RUNTIME) // 런타임에 유효하도록 함 public @interface ViewById { /** * 뷰의 ID 저장 * @return 뷰의 ID */ public int value() default -1; } 13년 7월 23일 화요일
  • 62. package yapp.aa.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ViewById { public int value() default -1; } 주석 빼면? 사실 몇 줄 안되는 어노테이션 13년 7월 23일 화요일
  • 63. ViewByIdResolver Class 리플렉션을 통해 Activity의 필드 중 @ViewById 어노테이션이 적용된 필드에 뷰를 찾아 설정해주는 역할을 수행 13년 7월 23일 화요일
  • 64. 어떻게 해야할까? • Reflection을 통해 액티비티의 필드를 가져옴 getDeclaredFields() • 가져온 필드에 적용된 어노테이션을 가져옴 getAnnotation(ViewById.class) • 어노테이션이 적용되었다면 값을 가져옴 null인 경우는 어노테이션이 적용되지 않은 필드 • value가 -1인지, 지정된 값인지에 따른 처리 • 액티비티에서 뷰를 찾아서 필드에 값을 설정 13년 7월 23일 화요일
  • 65. 이런 모양으로 시작해봅시다 public class ViewByIdResolver{ public static void resolve(Activity activity) { } } 13년 7월 23일 화요일
  • 67. 더 많은 것들을 할 수 있지 않을까? 13년 7월 23일 화요일
  • 68. findViewById 말고? • setOnClickListener? • 여기서 숙제 @Click 만들어보기 (사실 검색해도 나오긴 합니다 :D ) • 요점은 고민해보기 13년 7월 23일 화요일