21.09.13

.·2021년 10월 11일
0

playdata

목록 보기
33/35
post-thumbnail

DAY38

✍️어노테이션

[실행순서]
Test -> AnnotationTest (메소드 실행 테스트) -> Testclass (어노테이션 적용)
 		
1. Testclass에 메소드를 많이 만들어 놓고 Test의 어노테이션을 적용
2. AnnotationTest (메소드 실행 테스트) 확인 (성공, 실패 카운트) - 성공을 했는지 실패를 했는지
  • Test
//Test
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) // 런타임시에 정보를 클래스에 저장하겠다.
public @interface Test {

	
}
  • AnnotationTest
import java.lang.reflect.*;

public class AnnotationTest {

	// ()안에 클래스를 받아서 해당 클래스의 메소드를 실행 상태 카운트 할 메소드
	public static void test(Class clazz) throws Exception{
		
		int passed = 0; // 메소드 실행 성공 카운트
		int faild = 0; // 메소드 실행 실패 카운트
		
		for(Method m : clazz.getMethods()) { // 전체 6개의 메소드를 리턴해서 루프를 돈다.
			if(m.isAnnotationPresent(Test.class)) { //prn1() , prn3() , prn5()
				try {
					m.invoke(null); // 호출실행 
					passed++;
					System.out.println(m.getName());
				}catch(Throwable e){
					System.out.println("메소드 테스트 실패 : " + e.getCause()+"\t"+m.getName());
					faild++;
				}
			}//if
		}//for
			System.out.printf("실행 성공 %d  실패 %d",passed,faild);
	}//method
}//class
  • Testclass
public class Testclass {

	public static void prn() {
		// 어노테이션 Test를 안걸어놓아서 AnnotationTest if문 실행X
	}
	
	@Test
	public static void prn1() throws Exception {
		throw new Exception("에러를 내본다");
	}
	
	public static void prn2() {}
	
	@Test
	public static void prn3() {
		throw new RuntimeException("에러를 내볼까?");
	}
	
	public static void prn4() {}
	
	@Test
	public static void prn5() {}

	public static void main(String[] args) throws Exception {
		AnnotationTest.test(Testclass.class); // 랜덤은 아니고 쓰레드 형식으로 출력? -> 순서 중요 x

	}

}

 - 여러개의 어노테이션을 만들 때는 접근제한자 x
 - 각각의 Retention 줘야함

선언된 필드의 getter/setter 기능을 제어하는 기능을 어노테이션으로 구현 해보자.

  • PrintToString
//PrintToString.java (어노테이션)

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//실행 시점에서 어노테이션의 정보를 클래스에 저장하고 필드 위에 선언되어 적용한다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface PrintToString {

}
  • Student
public class Student {
	@PrintToString
	private String name;
	
	@PrintToString
	private int age;
	
	@PrintToString
	private String remark;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	@Override
	public String toString() {
		//return "Student [name=" + getName() + ", age=" + getAge() + ", remark=" + getRemark() + "]";
		return ToStringHelper.toString(this);
	}
	
	public static void main(String[] args) {
		Student sm = new Student();
		sm.setName("길동 프로님");
		sm.setAge(30);
		sm.setRemark("월요일은 힘들다");
		System.out.println(sm);
	}
	
	

}
  • BeansHelper
import java.lang.reflect.*;

// getter & setter 메소드의 원형을 만드는 코드를 작성하고
// 메소드를 찾아서 리턴하는 코드를 가진 메소드를 작성한다.

public class BeansHelper {
	//어노테이션이 필드에 선언되어 있기 때문에 선언된 필드로 getter/setter 원형을 찾아서
	//메소드를 제어하려한다.
	
	//getter에 해당하는 메소드 원형
	public static Method getGetterMethod(Class clazz, Field field) throws Exception{
		String prefix = "get";
		if(Boolean.class == field.getType() || boolean.class == field.getType()) {
			prefix = "is";
		}
		return getBeansMethod(clazz,field,prefix);
	}
	
	//setter에 해당하는 메소드 원형
	public static Method getSetterMethod(Class clazz, Field field,Class...paramType) throws Exception{
		return getBeansMethod(clazz,field,"set",paramType);
	}
	
	//메소드로 만들어서 리턴해준다.
	private static Method getBeansMethod(Class clazz, Field field, String prefix, Class... paramType)throws Exception {
		// name -> getName() -> get + Fieldname
		//getBeansMethod(clazz,field,prefix) -> (Student,name,get)
		String fieldName = field.getName();
		fieldName = prefix + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); //getName
		Method method = clazz.getMethod(fieldName, paramType);
		return method;
	}

	
}
  • ToStringHelper
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//getter 메소드를 리턴받아 / 출력하는 구문을 작성하는 클래스와 메소드
public class ToStringHelper {

	public static String toString(Object obj) {
		StringBuffer buffer = new StringBuffer();
		try {
			//1. 지정된 obj로 넘겨 받은 객체를 클래스로 변환
			Class clazz = obj.getClass(); //Student
			buffer.append(clazz.getName()).append("{");
			
			//2. 변환된 클래스의 필드를 반복문을 이용해서 추출한다.
			for(Field field : clazz.getDeclaredFields()) {
			//3. 전체 필드중에 PrintToString 어노테이션이 있는 필드를 추출한다.
				PrintToString pts = field.getAnnotation(PrintToString.class);
		
			//4. 조건문을 이용해서 null값이 아닌 클래스와 필드를 통해  get메소드를 실행한다.
				if(pts != null) {
					Method getter = BeansHelper.getGetterMethod(clazz, field);
					System.out.println(getter);
					Object value = getter.invoke(obj);
					buffer.append(field.getName()).append("=").append(value).append(",");
				} //if
			} //for
			buffer.append("}");
		}catch(Exception e) {
			
		}
		return buffer.toString();
	}//method

}//class

0개의 댓글