[211118] 교육 18일차

oxllz·2022년 1월 30일
0

교육

목록 보기
14/41

Annotaion

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
//
@Retention(RetentionPolicy.RUNTIME)
@interface Annot { }
//
@Annot
class Temp {
	@Annot
	public void print(){ }
}
//
public class Test152 {
	public static void main( String[] args ) throws Exception {
		Class<?> cls = Class.forName("banana.Temp");
		Annotation at = cls.getAnnotation( Annot.class );
		System.out.println( at );
		//
		Method mtd = cls.getMethod("print");
		Annotation at2 = mtd.getAnnotation( Annot.class );
		System.out.println( at2 );
	}
}

Annotaion : 일종의 인터페이스. 클래스, 멤버함수, 멤벼변수 위에 지정 가능

cls.getAnnotation( Annot.class )

  • 클래스에 Annot 이라는 이름을 가진 어노테이션이 지정되었는지 파악
  • 지정이 되었으면 Annot의 인스턴스에 대한 포인터 리턴
  • 안되었으면 null 리턴
  • 메서드의 경우에도 동일하다. mtd.getAnnotation
//어노테이션은 인터페이스고 함수를 선언할 수 있다.
@Retention(RetentionPolicy.RUNTIME)
@interface NoPrint {
	public int value() default 0;
	public int abcd() default 0;
}
//
class Calc {
	// value(), abcd() 함수를 통해서 리턴받을 값을 여기서 지정가능하다.
	@NoPrint(value=30,abcd=100)
	public int add( int i, int j ){ return (i+j);}
	public int minus( int i, int j ){ return (i-j);}
}
//
public class Test155 {
	public static void main( String[] args ) throws Exception {
		String l = "add";
		Object obj = new Calc();
		//
		Class<?> cls = obj.getClass();
		Method mtd = cls.getMethod( l, int.class, int.class );
		int r = (Integer)mtd.invoke( obj, 10, 20 );
		// Annotation 은 모든 어노테이션의 부모클래스
		// Annotation : 부모, NoPrint : 자식 (캐스팅 필요)
		NoPrint at = (NoPrint)mtd.getAnnotation( NoPrint.class );
		System.out.println( at.abcd() ); // 100
		if( at == null ) {
			System.out.println( r );
		}
		else if( at.value() == r ) {
			System.out.println( r ); // 30
		}
	}
}

@NoPrint(30) : 이런식으로 아무 키값없이 값을 지정하려면 value() 함수를 이용해야 한다.

@NoPrint(value=30,abcd=30) : 이런식으로 특정 키값을 지정하여 value 값을 지정하려면 함수 이름을 사용해야 한다.


String

public class Test157 {
	public static void main( String[] args ) {
		String t = "HelloWorld";
		String r = "HelloWorld";
		System.out.println( r == t ); // true
		String l = t.substring(2,5);
		System.out.println( l ); // llo
		// llo?? HelloWorld??
		System.out.println( r ); // Helloworld
	}
}

포인터의 비교는 같은 인스턴스를 가리킬때 == 이 true 나온다. ( 내용을 비교 할때는 equals )

"..." 로 생성한 인스턴스의 경우에 한해서 한번 생성한 인스턴스는 재활용한다. String t = "HelloWorld" 는 인스턴스가 재활용되기 때문에 메모리 소모가 거의 없다.

재활용되는 인스턴스는 다른 사람이 쓰고 있는데 내용을 바꾸면 영향이 가기 때문에 함부로 변경해서는 안된다. ( 영상을 올려서 같이 공유중인데 누군가 그 영상 파일을 손상시키는 것이라고 생각 )

따라서 String 의 모든 멤버함수는 내용을 바꾸지 않고 새로운 문자열을 만드는 형태로 동작한다.

public class Test158 {
	public static void main( String[] args ) {
		String l = "*";
		for( int i = 0 ; i < 100000 ; i++ ) {
        	// 쓸데없는 String 을 10만개 만들게 됨
			l = l + "*";
		}
		System.out.println( l );
	}
}

StringBuffer

public class Test159 {
	public static void main( String[] args ) {
		StringBuffer l = new StringBuffer("*");
		for( int i = 0 ; i < 100000 ; i++ ) {
			l.append("*");
		}
		System.out.println( l.toString() );	
	}
}

String 과 비슷하지만 자신의 내용을 변경시키는 형태로 동작하는 클래스
[********...]
자신의 내용에 붙이는 형태로 동작한다. 따라서 이 프로그램은 인스턴스 1개만 생기게 되므로 메모리가 절약된다.

0개의 댓글