티스토리 뷰

1.    요약

-      참조 타입의 종류 : 배열타입, 열거타입, 클래스. 인터페이스, 레코드

-      Staic은 지역변수나 매개변수에 사용할 수 없다.

-      매개변수는 지역변수로 간주하기에 지역변수와 같은 유효 범위를 갖는다.

-      패키지란 비슷한 기능을 가진 클래스끼리 묶은 것을 의미한다.

-      만약 다른 패키지에 있는 것을 사용하고 싶을 때는 import문을 사용해야 한다.

-      import문은 컨트롤 + 쉬프트 + O를 사용하면 자동으로 입력되지만, 만약 같은 이름의 클래스를 모두 사용할 때에는 직접 패키지명.클래스명으로 직접적으로 입력해야 한다.

-      Default 접근제한자는 접근제한자 중 아무것도 작성하지 않았을 때 자동으로 사용되는 접근제한자로, 같은 패키지에만 접근이 가능하다. (public과 같이 class에 사용가능)

-      Getter setter의 이름을 지을 때에는 get/set + 필드명으로 주로 짓는다. 다르게 지어도 가능하다.

 

2.    어노테이션 ( Annotation )

-      어노테이션은 적용할 때, @AnnotationName을 작성하여 사용할 수 있다.

-      어노테이션에서 속성을 기술할 때에는 String value ( ) ; 처럼 ( );을 붙어야 한다.

-      또한 어노테이션에서는 속성에 무조건 값을 지정해 줘야한다.

-      어노테이션에서 값을 지정해서 정의할 때는 int elementName ( ) default 5;로 작성

-      다른 클래스에서 지정할 때에는 @AnnotationName(value = “” , elementName =3);으로 작성해야 한다.


01. 어노테이션 1 - 위치고정

 

package org.zerock.myapp.annotation;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

// ElementType[] value();

// Target에서 오른 클릭을 하면 이렇게 Element Type 배열에 있는 원소를 사용하라고 적혀 있다. (**)

// ElementType의 원소는 열거 상수(ex.Week)로 되어있기에 이 중에서 골라야 한다.

// 열거상수 는 ElementType temp = ElementType.TYPE; 처럼 사용해야 한다. (****)

// @Target은 { } 배열로 이루어져 있기에, 다양하게 위치를 고정시킬 수 있다. (**)

 

// ElementType 열거 상수 중 TYPE_USE는 모든 곳에서 사용할 수 있게 해준다는 것인데,

// 완전히 모두 가능하게 하는 것이 아니라 메소드와 페키지 선언부에는 적용이 안된다. (**)

 

// 기본속성에만 값을 지정하면 되기에 @Target({ElementType.TYPE, ElementType.FIELD}) 도 가능하다.

@Target(value = {

             ElementType.TYPE,

             ElementType.FIELD,

             ElementType.METHOD,

             ElementType.CONSTRUCTOR, // 생성자

             ElementType.LOCAL_VARIABLE, // 지역변수

             ElementType.PARAMETER, // 매개변수

             ElementType.PACKAGE,

             ElementType.ANNOTATION_TYPE

             }) // 어노테이션 선언부 위치

// @Myannotation을 특정한 위치에만 적용할 수 있도록 위치를 제한시켰다. (****)

 

@Retention(RetentionPolicy.RUNTIME) // 배열이 아니기에 { }를 붙이지 않는다.

// 만약 어노테이션을 사용하고 import를 사용했을 때, 오류가 발생하면 값을 필요로 하는 경우가 많기에

// 컨트롤 + 오른쪽 클릭을 하여 어떤 값이 필요한지 파악해야 한다.

 

// @Retention은 어노테이션 붙였을 때, 어노테이션이 붙었다는 정보를 어디까지 유지하는 가를 결정하는 것이다.(***)

// 소스파일 내에서만 유지할 것인지, 클래스 내에서만 유지할 것인지, 런타임에서만 유지를 할 것인지 결정해야 한다.

// 대부분 런타임을 선택하여 사용한다. (***)

// ( ) 안에 들어가는 식별자는 컴파일러가 정확히 어떤 것을 의미하는지 출처를 알게 작성해야 한다.

 

@Myannotation // 기본적으로 어노테이션은 자기자신한테도 붙여줄 수 있다. 하지만 명확성을 위해 지양하자!

public @interface Myannotation {

 

//     TYPE 선언부란?

//     @Myannotation

//     public class Service { } 를 의미한다.

      

       // 속성 ( 정확히는 엘리먼트 ) 선언 ( like field )

       String value() default "-"; // 기본속성 (**)

       // 뒤에 ();를 붙어야 한다.

       // Annotation default 값이 설정되어 있지 않으면, 반드시!!! 값을 줘야 한다!! (**)

       int number () default 30; // 기본값 설정

 

} // end annotation

 

02. 어노테이션 2 - 위치

 

//@Myannotation - 1. 컴파일오류 발생 -패키지 선언문 위에는 어노테이션 사용이 불가능하다.

package org.zerock.myapp.annotation;

 

@Myannotation

public class Service2 { // 어노테이션의 위치 (***)

//@Myannotation public class Service2 { // OK!

//public @Myannotation class Service2 { // OK!! - @Myannotation을 사이에 작성하여도 사용가능하다.

      

//public class @Myannotation Service2 { // 3. 컴파일 오류 - class와 class명은 한 몸으로 생각하기에 class와 class명 사이에는 불가능하다.

      

       @Myannotation

       public String instanceField; // OK!

//     @Myannotation public String instanceField; // OK!

//     public @Myannotation String instanceField; // ok!

      

//     public String @Myannotation instanceField; // 4. 컴파일 오류!! - 타입과 타입은 한 몸이기에 사이에 어노테이션을 사용할 수 없다.  

      

      

       @Myannotation

       private static int staticField; // OK! 어노테이션은 정적이나 인스턴스 구분하지 않고 어디에서나 붙일 수 있다.

      

       @Myannotation

       public Service2(@Myannotation String instanceField, @Myannotation final double PI){ // OK!

             ;;

       } // default constructor - 생성자 OK!

      

//     public @Myannotation Service2(@Myannotation String instanceField, @Myannotation final double PI){

//           ;;

//     } // OK!!

      

//     public @Myannotation Service2(@Myannotation String instanceField, final @Myannotation double PI){

//           ;;

//     } // OK! - final 뒤에도 사용이 가능하다. , double 뒤에는 사용이 불가능 하다.

      

      

      

//     @Myannotation

//     static {

//          

//     } //static initializer - 2. 컴파일 오류 발생 - static initializer에서는 JVM이 구동하는 것이기에 오류가 발생한다. (**)

      

      

      

       @Myannotation

       private static final double PI = 3.14159; // OK!

      

//     @Myannotation private static final double PI = 3.14159; // OK!

//     private @Myannotation static final double PI = 3.14159; // ok!

//     private static @Myannotation final double PI = 3.14159; // ok!

//     private static final @Myannotation double PI = 3.14159; // OK!

      

      

//     private static final double @Myannotation PI = 3.14159; // 5. 컴파일 오류!! - 변수명을 2개로 인식해 버린다.

      

      

       @Myannotation

       public void staticMethod() {

            

             @Myannotation

             int temp; // OK! 이러한 지역변수에서도 어노테이션을 사용할 수 있다.

 

       } // OK!

      

       @Myannotation public void staticMethod2() { ;; } // OK!

//     public @Myannotation void staticMethod2() { ;; } // OK!

      

//     public void @Myannotation staticMethod2() { ;; } // 6. 컴파일 오류 - 타입과 이름이 한 몸이기에 사이에 어노테이션을 사용할 수 없다.

      

       @Myannotation

       public void instanceMethod(@Myannotation int age) { // OK! 매개변수에서도 어노테이션을 사용할 수 있다.

            

             @Myannotation

             int temp; // OK!          

//           @Myannotation int temp; // OK!

            

//           int @Myannotation temp; // 7. 컴파일러 오류! - 타입과 변수 명 사이에는 불가능하다.

            

       } // instanceMethod

      

//    어노테이션은 패키지 선언문과 static initializer, 그리고 타입과 변수 명 사이를 제외한 모든 곳에 사용이 가능하다.

 

} // end class

 

03. 어노테이션 응용 - clazz 객체 

 

package org.zerock.myapp.annotation;

 

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

 

public class MyAnnotationExample { // 어노테이션 - clazz 객체 (******)

      

       // xxx.java ---> compile ----> xxx.class

      

      

       // Java Reflection API를 이용하여, Service 클래스에 붙여놓은

       // MYannotation 이름의 어노테이션 정보를 이용하여 무엇인가를 합시다!!

       // Java Reflection API는 class 파일의 모든 정보를 반영/반사하는 것이다.

      

       // clazz는 .class 파일을 클래스로더가 바이트를 읽어다가 class에 대한 모든 정보를 class타입의 clazz 객체를 넣은 것을 의미한다.

      

       public static void main (String [] args ) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

            

             Class clazz = Service.class; // (******)

             // 이 말은 clazz라는 객체는 class 타입이며, service 클래스에 대한 모든 정보를 가지고 있다는 것이다.

             // 그리고 그 정보를 모두 불러왔다는 의미이다.

             // .class가 붙으면 clazz 객체이다.

             // clazz는 메소드 영역에 저장된다.

             // 이를 통해서 객체를 얻었기에 인스턴스멤버일지라도 new연산자를 사용하지 않아도 괜찮다.

            

             // 메소드 영역에 아래의 Service 타입에 대한 정보를 모두 가지고 있는

             // Clazz객체가 없으면, new 연산자로 객체를 생성할 수 없다!!

             // , classNotFoundException 이란 오류가 발생하게 된다.

            

             System.out.println(clazz); // clazz가 가지고 있는 class파일의 위치를 출력

             // 출력결과 : class org.zerock.myapp.annotation.Service

            

             Method[] methods = clazz.getDeclaredMethods(); // 마우스를 올려 놓자 static이 없는 것을 보아 인스턴스멤버임을 알 수 있다.

             // import문 주의하자!!

             // getDeclaredMethods는 메소드를 뽑아 내라는 것이다.

            

             for ( Method method : methods ) { // 메소드 출력 방법 (***)

                   

                    System.out.println(method);

                   

             } // enhanced for - 메소드와 매개변수를 출력한다.

            

             // enhanced for 출력결과

//           public void org.zerock.myapp.annotation.Service.instanceMethod(int)

//           public void org.zerock.myapp.annotation.Service.staticMethod()

            

//           Service s = new Service(null, 10.0);

            

//     ==========================================================================================================

            

//           0. 메소드 지정

            

             Method instanceMethod = methods[0];

             Method staticMethod = methods[1];

            

//     ==========================================================================================================

            

//           1. 어노테이션의 존재 확인

            

             // 어노테이션이 여러개 붙어있을 수 있으므로 어노테이션을 지정해줌으로써 확인하는데 도움을 준다.

            

             boolean isPresent = instanceMethod.isAnnotationPresent(Myannotation.class);

             // 마이어노테이션이 인스턴스메소드에 있는가 boolean 타입으로 확인해 준다.

            

             System.out.println(isPresent); // true로 출력

            

//     ==========================================================================================================

            

//           2. 어노테이션 정보 추출

            

             Myannotation myAnnotation = instanceMethod.getAnnotation(Myannotation.class); // 어노테이션은 실행할 때 클레스처럼 쓰인다.

             System.out.println(myAnnotation); // 출력 : @org.zerock.myapp.annotation.Myannotation(value="-", number=30)

             // Myannotation의 완전한 이름이 나온 후에 속성이 나오게 된다.

            

             // 잘 모르는 객체의 경우 출력을 하여 어떤 것인지 파악하는 것이 도움을 준다!!

             // 어노테이션은 메타 데이터로 활용된다.

            

//     ==========================================================================================================

            

//           3. 어노테이션 속성 추출하기

            

             String value = myAnnotation.value();

             int number = myAnnotation.number(); // 값을 리턴받을 때, 메소드처럼 시행되기에 ( );를 붙어야 한다.

             System.out.println(String.format("value : %s, number : %d", value, number)); // (*****)

             // 출력 결과 : value : -, number : 30

             // format은 원하는 형식으로 출력하게 해준다.

             // %s %d는 포멧팅 기호라고 부른다.

             // 그냥 " %s "를 붙이면 타입에 맞게 조절해준다. ( 만능 기호 ) ( **** )

            

             // 이때 format은 클래스 명을 붙인 String.format으로 활용하였기에 static 정적멤버인 정적 메소드이다.

            

//     ==========================================================================================================

            

//           5. 어노테이션 활용하기

            

//           instanceMethod.invoke(value, args) // 메소드 호출시키기 - 매개변수에 주는 값을 전달인자(arg)라고 한다.

            

//     ==========================================================================================================

            

//           6. object

//           Myannotation이 붙어 있는 메소드가 호출될 때, 메소드 호출로그를 우리가 직접 코딩하는 것이 아니라.

//           자동으로 메소드 호출로그를 출력하는 기능을 구현하는데

//           어노테이션의 메타데이터를 사용하자!!

            

             System.out.println("-- [" + instanceMethod.getName() + "] ----");

             for ( int i =0 ; i< number; ++i) {

                    System.out.println(value); // vlaue의 값을 가져와 출력하게 함.

             } // classical for(****)

            

             instanceMethod.invoke(new Service("Yoseph", 23), 100); // 메소드 호출(?) - 오류뜰때는 노랑박스 클릭

            

            

//           . 어노테이션 존재 확인

            

             boolean isPresent2 = staticMethod.isAnnotationPresent(Myannotation.class); // Myannotation.classclazz에 해당한ㄷ다.

             // 마이어노테이션이 스테이틱메소드에 있는가 boolean 타입으로 확인해 준다.

            

             System.out.println(isPresent2); // true로 출력

            

       } // main class

 

} // end class

 

04. String.format

 

package Practice;

 

import java.util.Arrays;

 

public class Sample01 { // format 출력 (*****)

      

       public static void main (String[] args) {

            

             String name = "조민주";

             int age = 23;

             double weight = 60.2;

             double height = 162.0;

            

//           String.format("formatting string", 가변인자); // 메소드를 사용할 때는 기능과 return 값을 알아야 한다.

             // 가변인자에는 0개 이상의 값들을 넣을 수 있다.

            

             // Object?

             // 1. class

             // 2. 모든 클래스의 조상 클래스 - object란 이름의 클래스

            

             String result1 = String.format("1. name : %s", name);

             // 기호 : %s ( 문자열, 만능 ) ,  %d ( 정수 ) ,  %f ( 실수 )

            

             System.out.println(result1); // 1. name : 조민주

            

             String result2 = String.format("2. age : %s", age);

             System.out.println(result2); // 2. age : 23

            

             String result3 = String.format("3. weight : %s", weight);

             System.out.println(result3); // 3. weight : 60.2

            

             String result4 = String.format("4. height : %s", height);

             System.out.println(result4); // 4. height : 162.0

            

//           한 번에 출력하기

            

             String result = String.format(">>>> name : %s, age : %s, weight : %s, height : %s", name, age, weight, height);

             System.out.println(result); // 출력 : >>>> name : 조민주, age : 23, weight : 60.2, height : 162.0

            

//           배열의 각 원소의 값을 하나의 문자열로 출력하라!

            

             int [] arr = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };

            

             String intarr = String.format("int arr = %s, %s, %s, %s, %s, %s, %s, %s, %s",  arr [0], arr [1],  arr [2],  arr [3], 

                           arr [4],  arr [5],  arr [6],  arr [7],  arr [8]); // 배열의 인덱스는 0번 부터 시작한다!!

             System.out.println(intarr); // int arr = 1, 2, 3, 4, 5, 6, 7, 8, 9

            

             System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

            

//           String.format(intarr, args); (******)

            

       /**

        *

        *  새로운 주석 방법!

        * 

        *  */

            

            

       } // main

 

} // end class

728x90
댓글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
최근에 올라온 글
Total
Today
Yesterday
공지사항