목차

 

  1. Custom Annotation 만들고 사용하기

 

  2. @RequestMapping 들여다 보기

 

 

 

Custom Annotation 만들고 사용하기

 

   ※ Custom Annotation 생성

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

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
	String name()	default "Gyu";		//name값을 설정할 수 있으며, 아무런 값을 넣지 않으면 Gyu가 들어갑니다.
	String value();							//value값을 설정할 수 있으며, 아무런 값을 넣지 않으면 Syntax error가 발생합니다.
	int count()	default 1;							//기본 자료형도 사용할 수 있습니다
	String[] arrName()	default "first Index";		//배열값을 넣을 수 있습니다. { }안에 값을 넣어 삽입. 
	TestEnumType[] testEnumType()		default TestEnumType.FIRST;	//enum타입의 값을 설정할 수 있습니다.
	AnnoDateTime annoDateTime();	//Annotation안에 또 다른 Annotation값을 넣을 수 있습니다.
}

@Retention(RetentionPolicy.RUNTIME)
@interface AnnoDateTime {
	String yymmdd();
	String hhmmss();
}

enum TestEnumType {
	FIRST, FINAL
}

 

Custom Annotation을 작성하기 위해 몇 가지 규칙이 존재합니다.

 

1. 요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용된다.

2. 요소의 ()안에 매개변수를 선언할 수 없다.

3. 예외를 선언할 수 없다.

4. 요소를 타입 매개변수로 정의할 수 없다.

5. 어노테이션의 각 요소는 기본값을 가질 수 있다.

 

위 규칙을 생각하며 어노테이션을 작성하면 됩니다.

 

   ※ Custom Annotation 적용

 

   - 클래스에 선언

@MyAnnotation(value = "First Text", annoDateTime = @AnnoDateTime(yymmdd = "190924", hhmmss = "101147"))
public class AnnotationHandler {
	
	public String myField = null;
	
	public void doThis() {
		
	}
	
	public void doThat() {
		
	}
	
}

 

   - 클래스 필드에 선언

public class AnnotationHandler {
	
	@MyAnnotation(value = "First Text", annoDateTime = @AnnoDateTime(yymmdd = "190924", hhmmss = "101147"))
	public String myField = null;
	
	public void doThis() {
		
	}
	
	public void doThat() {
		
	}
	
}

 

   - 메서드에 선언

public class AnnotationHandler {
	
	public String myField = null;
	
	@MyAnnotation(value = "First Text", annoDateTime = @AnnoDateTime(yymmdd = "190924", hhmmss = "101147"))
	public void doThis() {
		
	}
	
	@MyAnnotation(value = "First Text", annoDateTime = @AnnoDateTime(yymmdd = "190924", hhmmss = "101147"))
	public void doThat() {
		
	}	
}

 

   

  ※ 자바 리플렉션으로 커스텀 어노테이션 사용하기

 

@Retention(RetentionPolicy.RUNTIME)값으로 설정한 Custom Annotation은 런타임 시점에 어노테이션 정보를 이용하여 코드를 생성합니다.

이러한 이유로 RUNTIME옵션을 설정한 Custom Annotation은 자바 리플렉션을 사용하여 선언한 어노테이션 값을 가져옵니다.

 

프로그램 구동 시, Custom Annotation에서 어떤 값이 넘어오는지 확인해보는 테스트를 해보겠습니다.

 

MyAnnotation.java

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

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
	String name()	default "Gyu";		//name값을 설정할 수 있으며, 아무런 값을 넣지 않으면 Gyu가 들어갑니다.
	String value();							//value값을 설정할 수 있으며, 아무런 값을 넣지 않으면 Syntax error가 발생합니다.
	int count()	default 1;							//기본 자료형도 사용할 수 있습니다
	String[] arrName()	default "first Index";		//배열값을 넣을 수 있습니다. { }안에 값을 넣어 삽입. 
	TestEnumType[] testEnumType()		default TestEnumType.FIRST;	//enum타입의 값을 설정할 수 있습니다.
	AnnoDateTime annoDateTime();	//Annotation안에 또 다른 Annotation값을 넣을 수 있습니다.
}

@Retention(RetentionPolicy.RUNTIME)
@interface AnnoDateTime {
	String yymmdd();
	String hhmmss();
}

enum TestEnumType {
	FIRST, FINAL
}

 

AnnotationHandler.java

@MyAnnotation(value = "Class => AnnotationHandler", testEnumType = TestEnumType.FINAL,annoDateTime = @AnnoDateTime(yymmdd = "091005", hhmmss = "000000"))
public class AnnotationHandler {
	
	@MyAnnotation(value = "Field => myField", count = 10, annoDateTime = @AnnoDateTime(yymmdd = "131224", hhmmss = "210556"))
	public String myField = null;
	
	@MyAnnotation(value = "Method => doThis()", testEnumType = TestEnumType.FIRST, annoDateTime = @AnnoDateTime(yymmdd = "190924", hhmmss = "101147"))
	public void doThis() {
		
	}
	
	@MyAnnotation(value = "Method => doThat()", testEnumType = TestEnumType.FINAL, annoDateTime = @AnnoDateTime(yymmdd = "180728", hhmmss = "181447"))
	public void doThat() {
		
	}
	
}

 

AnnotationStudy.java

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class AnnotationStudy {

	public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
		
		//자바 리플렉션을 사용해 Class정보, getField(필드 정보), getMethod(메서드 정보)를 얻어옵니다.
		Class<AnnotationHandler> cls = AnnotationHandler.class; 	
		Field field = AnnotationHandler.class.getField("myField");
		Method thisMethod = AnnotationHandler.class.getMethod("doThis");
		Method thatMethod = AnnotationHandler.class.getMethod("doThat");

		//각 클래스, 필드, 메서드에 걸려있는 Annotation의 정보를 얻습니다.
		Annotation[] classAnnotations = cls.getDeclaredAnnotations();
		Annotation[] fieldAnnotations = field.getDeclaredAnnotations();
		Annotation[] thisMethodAnnotations = thisMethod.getDeclaredAnnotations();
		Annotation[] thatMethodAnnotations = thatMethod.getDeclaredAnnotations();
		
		//클래스, 메서드, 필드에 적용되어 있는 Annotation정보들을 추출합니다.
		printAnnotation(classAnnotations);
		printAnnotation(fieldAnnotations);
		printAnnotation(thisMethodAnnotations);
		printAnnotation(thatMethodAnnotations);
		
	}

	public static void printAnnotation(Annotation[] annotations) {
		
		for(Annotation annotation : annotations) {
			if(annotation instanceof MyAnnotation) {
				MyAnnotation myAnnotation = (MyAnnotation)annotation;
				
				System.out.println("String name() : " + myAnnotation.name());
				System.out.println("String value() : " + myAnnotation.value());
				System.out.println("int count() : " + myAnnotation.count());
				System.out.println("AnnoDateTime annoDateTime() yymmdd : " + myAnnotation.annoDateTime().yymmdd());
				System.out.println("AnnoDateTime annoDateTime() hhmmss : " + myAnnotation.annoDateTime().hhmmss());
				System.out.println("TestEnumType[] testEnumType() : " + myAnnotation.testEnumType());
				
				for(String str : myAnnotation.arrName()) {
					System.out.println("String[] arrName() : " + str);
				}
			}
		}
		
		System.out.println();
		
	}
}

 

출력 로그

위 소스를 보면 알다시피, RUNTIME에서 동작하는 어노테이션들은 전부 리플렉션을 사용해서 객체의 정보를 얻고, 어노테이션의 정보도 얻습니다.

 

커스텀 어노테이션을 생성해서 사용하면 반복적으로 코딩해야 하는 부분들도 많이 줄일 수 있고 더 비지니스로직에 집중할 수 있는 장점이 있습니다.

 

 

@RequestMapping 들여다 보기

 

Custom Annotation을 만들어봤으면, java 또는 Spring에서 제공하는 Annotation은 어떻게 생겼는지, 어떤식으로 구성되어 있는지 궁금하실 겁니다.

 

사실, Annotation내용을 포스팅하는 이유의 80%이상이 Annotation의 동작방식과 구성요소들을 알아보고, 직접 만들어보며 아무런 생각없이 사용하던 Annotation을 이해하자는 취지이기 때문에 @RequestMapping을 확인해보면 좀 더 친숙하게 다가갈 수 있을꺼라 생각합니다.

 

   ※ 구성 요소

 

@RequestMapping annotation 사용

위 소스는 @ReqeustMapping을 사용한 모습입니다. 익숙한 value값과 method값을 볼 수 있을 것 입니다.

실제 사용에 있어서 annotation의 인수가 하나뿐이면 value값을 지칭하지 않고 사용할 수 있습니다.

즉, @RequestMapping(value = "/cmm/cmmPlayer.do") 대신 @RequestMapping("/cmm/cmmPlayer.do")처럼 사용할 수 있습니다. (annotation 변수명이 value인 값만 가능)

 

그렇다면 세부적으로 어떻게 동작할까요?

 

@RequestMapping annotation 구조

위 소스는 직접 @RequestMapping 어노테이션을 타고 들어가서 본 내용입니다. 이젠 익숙한 내용들이 보일 것 입니다.

 

@Target({ElementType.METHOD, ElementType.TYPE})

해당 annotation은 매서드와 클래스, 인터페이스, enum에서 사용하도록 Target을 설정하겠다는 의미입니다.

 

@Retention(RetentionPolicy.RUNTIME)

해당 어노테이션을 런타임 시점에서 실행시키겠다는 의미입니다.

 

 

@RequestMapping annotation 구조-2

@RequestMapping의 핵심 요소인 String value() default { };RequestMethod[] method() defalut { };를 확인할 수 있습니다. value에 Mapping할 주소를 넣어주면 런타임 시점에 해당 주소와 URI는 서로 연결되게 됩니다.

 

또한, Request방식을 설정할 때 method = RequestMethod.GET 과 같이 GET호출 POST호출 등을 설정할 수 있습니다.

자료형인 RequestMethod[]를 확인해보면 GET, POST, PUT, PATCH 등과 같이 다양한 옵션이 enum으로 설정되어 있습니다.

 

RequestMethod enum 내부구조

 

이제 어느정도 Annotation의 구조가 눈에 파악될 것 입니다. 하지만, 더 깊은 세부 로직까지 아직은 알 필요가 없다고 생각하여 이정도로 정리하겠습니다.

 

※ 잘못된 내용이 있거나, 설명이 불충분한 부분이 있다면 답변 부탁드립니다.

 

 

Reference

 

 

목차

 

1. Annotation

 

2. Annotation 핵심 요소

 

 

Annotation

 

※Annotation 이란?

 

어노테이션 이란, 본래의 의미는 주석이라는 뜻이며 인터페이스를 기반으로 한 문법 입니다.(실제 Annotation을 생성하는 방식에서 @interface를 사용합니다.)

실제 메타 데이터로 이용되며 클래스, 메서드, 변수, 매개변수 및 패키지 등에 주석처럼 달아서 사용합니다.

 

@Controller
public class TestController {
	...
}

 

※ Annotation 사용이유

 

기존의 자바 웹 애플리케이션들은 대부분 설정값을 XML파일에 명시하여 관리했습니다. 변경될 수 있는 데이터들을 코드가 아닌 외부 설정 파일(XML)에 분리하기 때문에, 재컴파일 없이도 쉽게 변경사항을 저장할 수 있었습니다.

하지만, 프로그램 작성을 위해 매번 많은 설정을 해야하며, 수 많은 설정파일들을 관리해야 했습니다. (웹 애플리케이션의 규모가 커지면 그만큼 많은 설정 파일들을 관리해야 했습니다.)

 

이러한 문제점을 해결하기 위해 고안된 문법이 Annotation입니다,

 

어노테이션을 사용하면 데이터에 대한 유효성 검사조건을 보다 쉽게 파악할 수 있게 되며 코드가 깔끔해집니다.

단순히 부가적인 표현뿐만 아니라 리플렉션을 이용하면 어노테이션 지정만으로 원하는 클래스를 주입할 수 있습니다.

 

※ Annotation 용도

 

1. @Override 어노테이션 처럼 컴파일러를 위한 정보를 제공하기 위한 용도

2. 스프링 프레임워크의 @Controller 어노테이션 처럼 런타임리플렉션을 이용해서 특수 기능을 추가하

   기 위한 용도

3. 컴파일 과정에 어노테이션 정보로부터 코드를 생성하기 위한 용도

 

 

Annotation 핵심 요소

 

※ Annotation 종류

 

  • built-in Annotation

      - 이미 java에 내장되어 있는 어노테이션을 built-in Annotation 이라고 합니다.

      - 주로 컴파일러를 위한 위한 것으로 컴파일러에게 유용한 정보를 제공합니다.

      

      @Override

      - 선언한 메서드가 오버라이드 되었다는 것을 나타냅니다.

      - 만약 상위(부모) 클래스(또는 인터페이스)에서 해당 메서드를 찾을 수 없다면 컴파일 에러를 발생 시킵니다.

  

      @Deprecated

      - 해당 메서드가 더 이상 사용되지 않음을 표시합니다.

      - 만약 사용할 경우 컴파일 경고를 발생 시킵니다.

 

      @SuppressWarnings

      - 선언한 곳의 컴파일 경고를 무시하도록 합니다.

 

      @SafeVarargs

      - Java7 부터 지원하며, 제너릭 같은 가변인자의 매개변수를 사용할 때의 경고를 무시합니다. 

 

      @FunctionalInterface

      - Java8 부터 지원하며, 함수형 인터페이스를 지정하는 어노테이션입니다.

      - 오버라이딩 어노테이션과 마찬가지로 실수를 미연에 방지하기 위해 사용됩니다.

 

     

@Service("LoginService")
public class LoginServiceImpl implements LoginService{

  @Override
  public UserVO selectUser(UserVO userVO) {
      return loginDAOImpl.getUserInfo(userVO);
  }
}

 

  • Meta Annotation

      - 어노테이션에 사용되는 어노테이션으로 해당 어노테이션의 동작대상을 결정합니다.

      - 주로 새로운 어노테이션을 정의할 때 사용합니다.

 

     @Retention

     - 자바 컴파일러가 어노테이션을 다루는 방법을 기술하며, 어노테이션이 유지되는 기간을 지정하는데

       사용합니다.

     - 세 가지 유지 정책(retention policy)를 사용할 수 있습니다.

 

       <사용 종류>

       RetentionPolicy.SOURCE : 컴파일 전까지만 유효. (컴파일 이후에는 사라짐)

       RetentionPolicy.CLASS : 컴파일러가 클래스를 참조할 때까지 유효.

       RetentionPolicy.RUNTIME : 컴파일 이후에도 JVM에 의해 계속 참조가 가능. (리플렉션 사용)

 

     @Target     

     - 어노테이션이 적용할 위치를 지정합니다.

     - 여러 개의 값을 지정할 때는 배열에서 처럼 괄호 { } 를 사용해야 합니다.

 

       <사용 종류>     

       ElementType.PACKAGE : 패키지 선언

       ElementType.TYPE : 타입 선언

       ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언

       ElementType.CONSTRUCTOR : 생성자 선언

       ElementType.FIELD : 멤버 변수 선언

       ElementType.LOCAL_VARIABLE : 지역 변수 선언

       ElementType.METHOD : 메서드 선언

       ElementType.PARAMETER : 전달인자 선언

       ElementType.TYPE_PARAMETER : 전달인자 타입 선언

       ElementType.TYPE_USE : 타입 선언

 

     @Documented

     - 해당 어노테이션을 javadoc에 포함시킵니다.

 

     @Inherited   

     - 어노테이션의 상속을 가능하게 합니다.

 

     @Repeatable

     - 연속적으로 어노테이션을 사용할 수 있게 해줍니다.

 

@Color(name = "red")
@Color(name = "blue")
@Color(name = "green")
class Shirt {
	...
}

 

@Inherited // 상속
@Documented // 문서에 정보가 표현
@Retention(RetentionPolicy.RUNTIME) // 컴파일 이후에도 JVM에 의해서 참조가 가능합니다
@Retention(RetentionPolicy.CLASS)   // Compiler가 클래스를 참조할 때까지 유효합니다
@Retention(RetentionPolicy.SOURCE)  // 컴파일 이후 이후 사라집니다
@Target({
		ElementType.PACKAGE, // 패키지 선언시
		ElementType.TYPE, // 타입 선언시
		ElementType.CONSTRUCTOR, // 생성자 선언시
		ElementType.FIELD, // 멤버 변수 선언시
		ElementType.METHOD, // 메소드 선언시
		ElementType.ANNOTATION_TYPE, // 어노테이션 타입 선언시
		ElementType.LOCAL_VARIABLE, // 지역 변수 선언시
		ElementType.PARAMETER, // 매개 변수 선언시
		ElementType.TYPE_PARAMETER, // 매개 변수 타입 선언시
		ElementType.TYPE_USE // 타입 사용시
})
public @interface NesoyAnnotation{
	/* enum 타입을 선언할 수 있습니다. */
	public enum Quality {
		BAD, GOOD, VERYGOOD
	}

	/* String은 기본 자료형은 아니지만 사용 가능합니다. */
	String value() default "NesoyAnnotation : Default String Value";

	/* 배열 형태로도 사용할 수 있습니다. */
	int[] values();

	/* enum 형태를 사용하는 방법입니다. */
	Quality quality() default Quality.GOOD;
}

<출처 : https://nesoy.github.io/articles/2018-04/Java-Annotation>

 

 

※ Annotation 사용구분

 

  • Marker Annotation

      - 이름으로 구분하기 위하여 사용하며 추가적인 데이터를 필요로 하지 않습니다.

      - 멤버 변수가 없으며, 단순히 표식으로서 사용된다. 컴파일러에게 어떤 의미를 전달합니다.

 

create

public @interface TestAnnotation { }

use

@TestAnnotation
public void setMethode() {
		...
}

 

  • Single-Value Annotation

      - 간단한 신텍스를 이용하며 단일 데이터를 필요로 함

      - 멤버로 단일변수만을 갖는다. 단일변수 밖에 없기 때문에 (값)만을 명시하여 데이터를 전달할 수 있습니다.

 

create

public @interface TestAnnotation {
	String doSomething();
}

use

@TestAnnotation("What to do")
public void setMethode() {
		...
}

 

  • Full Annotation

      - 복잡한 신텍스이며, 다중 데이터를 사용하며 name=value 형태를 취함 --> 데이터가 Array인 경우 "{ }"를 이용

      - 멤버로 둘 이상의 변수를 갖는 어노테이션으로, 데이터를 (Key = Value)의 형태로 전달합니다.

 

create

public @interface TestAnnotation {
	String doSomething();
	int count;
	String date();
}

use

@TestAnnotation(doSomething="What to do", count=1, date="09-09-2019")
public void setMethode() {
		...
}

 

※ 잘못된 내용이 있거나, 설명이 불충분한 부분이 있다면 답변 부탁드립니다.

 

Reference

 

java 스타일 가이드


http://myeonguni.tistory.com/1596

1. 레퍼런스가 영원히 영역을 벗어남


void A()

{

School s = new School();

}


메소드가 종료되면 's'라는 레퍼런스도 죽어버립니다.


2. 레퍼런스에 다른 객체를 대입


School s = new School();

s = new School();


레퍼런스 's'에 새로운 객체를 대입하면 첫번째 객체는 버려집니다.


3. 레퍼런스를 직접 'null'로 설정


School s = new School();

s = null;


's'를 해제하면 첫번째 객체는 버려집니다.

즉, 레퍼런스 's'가 아무 객체도 참조하지 않는 것입니다.



레퍼런스가 참조하지 않는 객체는 가비지 컬렉션의 대상이 되어 자동으로 정리됩니다.


http://01027921288.tistory.com/entry/JAVA%EA%B0%9D%EC%B2%B4%EB%A5%BC-%EC%A0%9C%EA%B1%B0%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95

싱글톤 패턴 (singleton pattern)

디자인 패턴중 하나인 싱글톤에 대해서 알아보자. 여러분은 static 에 대한 개념이 생겼기 때문에 싱글톤을 이해하는것이 어렵지 않을 것이다.

싱글톤은 단 하나의 객체만을 생성하게 강제하는 패턴이다. 즉 클래스를 통해 생성할 수 있는 객체는 Only One, 즉 한 개만 되도록 만드는 것이 싱글톤이다.

다음의 예를 보자.

SingletonTest.java

class Singleton {
    private Singleton() {
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton = new Singleton();
    }
}

위와 같은 코드를 작성하면 컴파일 에러가 발생한다. 왜냐하면 Singleton 클래스의 생성자에 private 키워드로 외부 클래스에서 Singleton 클래스의 생성자로의 접근을 막았기 때문이다. 이렇게 생성자를 private 으로 만들어 버리면 외부 클래스에서 Singleton 클래스를 new 를 이용하여 생성할 수 없게 된다.

new를 이용하여 무수히 많은 객체를 생성한다면 싱글톤의 정의에 어긋나지 않겠는가? 그래서 일단 new로 객체를 생성할 수 없도록 막은 것이다.

그렇다면 Singletone 클래스의 객체는 어떻게 생성할 수 있을까? 다음처럼 코드를 작성 해 보자.

class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        return new Singleton();
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
    }
}

위와 같이 코드를 변경하면 이제 getInstance라는 static 메소드를 이용하여 Singleton 객체를 돌려 받을 수 있다. 하지만 getInstance를 호출 할 때마다 새로운 객체가 생성되게 된다. 그렇다면 싱글톤이 아니다. 어떻게 해야 할까?

다음처럼 코드를 작성해 보자.

class Singleton {
    private static Singleton one;
    private Singleton() {
    }

    public static Singleton getInstance() {
        if(one==null) {
            one = new Singleton();
        }
        return one;
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton1 == singleton2);
    }
}

Singleton 클래스에 one 이라는 static 변수를 두고 getInstance 메소드에서 one 값이 null 인 경우에만 객체를 생성하도록 하여 one 객체가 단 한번만 만들어지도록 했다.

getInstance 메소드의 동작원리를 살펴보자.

최초 getInstance가 호출 되면 one이 null이므로 new에 의해서 객체가 생성이 된다. 이렇게 한번 생성이 되면 one은 static 변수이기 때문에 그 이후로는 null이 아니게 된다. 그런 후에 다시 getInstance 메소드가 호출되면 이제 one은 null이 아니므로 이미 만들어진 싱글톤 객체인 one을 항상 리턴하게 된다.

main 메소드에서 getInstance를 두번 호출하여 각각 얻은 객체가 같은 객체인지 조사 해 보았다. 역시 예상대로 "true"가 출력되어 같은 객체임을 확인 할 수 있다.

싱글톤 패턴은 static에 대한 이해만 있다면 참 알기쉬운 패턴 중 하나이다.


https://wikidocs.net/228

Inner 클래스와 Outer 클래스
– 다른 클래스 내부에 삽입된 클래스
– 외부 클래스를 Outer 클래스 내부 클래스를 Inner 클래스라고 한다.
– Outer 클래스의 인스턴스가 생성된 후에 Inner 클래스의 인스턴스 생성이 가능하다.
– Outer 클래스의 인스턴스를 기반으로 Inner 클래스의 인스턴스가 생성된다.


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
public class Test{
 
public static void main(String[] args) {
Outer o1 = new Outer("o1");
Outer o2 = new Outer("o2");
Outer.Inner oi1 = o1.new Inner(); // 외부 참조방법
Outer.Inner oi2 = o2.new Inner(); // Outer 의 참조변수를 기반으로 Inner의 인스턴스를 생성
// Inner의 인스턴스는 Outer의 인스턴스에 종속적이다.
}
}
 
class Outer{
private String name;
public Outer(String name) {
this.name = name;
}
void print(){
System.out.println(name);
}
class Inner{
Inner(){
print();  // Outer 클래스의 메소드 직접접근 가능
}
}
}


Nested 클래스
– Inner 클래스에 static 키워드가 선언된 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test{
 
public static void main(String[] args) {
Outer o = new Outer();
Outer.Nested on = new Outer.Nested(); // 외부 참조방법
on.print();
}
}
 
class Outer{
 
Outer(){
Nested n = new Nested(); // Outer 클래스에서 객체생성가능
n.print();
}
static class Nested{
public void print(){
System.out.println("nested");
}
}
}


Local 클래스
– 메소드 내에 정의된 클래스
– 메소드 내에서만 참조변수 선언이 가능하다


1
2
3
public interface Printable {
public void print();
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test{
 
public static void main(String[] args) {
Outer o = new Outer();
Printable p = o.create("print");   // 메소드 내에서만 참조변수 선언이 가능하다.
// 따라서 인터페이스 Printable 을 구현하도록 한후 리턴된 인스턴스를 Printable 참조변수로 참조한다.
p.print(); // Printable 의 print 메소드를 호출하면 오버라이딩에 의해서 Local 클래스의 print 메소드가 호출된다.
}
}
 
class Outer{
public Printable create(final String print){ // final 선언된 변수만 Local 클래스내에서 접근이 가능하다.
class Local implements Printable{
@Override
public void print() {
System.out.println(print);
}
}
return new Local();
}
}


Anonymous 클래스
– 클래스의 이름이 정의되지 않은 클래스

– 인터페이스의 인스턴스를 리턴한다.


1
2
3
public interface Printable {
public void print();
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test{
 
public static void main(String[] args) {
Outer o = new Outer();
Printable p = o.create("print");  
p.print();
}
}
 
class Outer{
public Printable create(final String print){
return new Printable() {
@Override
public void print() { // Printable 에 정의된 미완성 메소드의 내부를 바로 채워준다면 인터페이스의 인스턴스 생성을 허용하는 java 문법  
System.out.println(print);
}
};
}
}


http://ccm3.net/archives/4679


http://jsnote.tistory.com/21

1. 접근제어자

- 접근제어자는 멤버 또는 클래스에 사용되어 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 함

- 접근제어자는 생략가능하며 생략했을 때는 자동으로 default 임을 뜻하게 된다. 따라서 default 일경우에는 접근제어자를 지정하지 않는다.

- 접근제어자가 사용될 수 있는 곳 : 클래스, 멤버변수, 메서드, 생성자

1) private : 같은 클래스 내에서만 접근 가능

2) default : 같은 패키지 내에서만 접근 가능

3) protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근 가능

4) public : 접근 제한이 전혀 없다.


제어자 

같은 클래스

같은 패키지 

자손 클래스 

 전체

 public

 

 

 

 

 protected

 

 

 

 

 default

 

 

 

 

 private

 

 

 

 


- 접근 범위 : private < default < protected < public 순으로 보다 많은 접근을 허용한다



출처: http://88240.tistory.com/448 [shaking blog]

인터페이스추상 클래스
클래스가 아니다클래스다
클래스와 관련이 없다클래스와 관련이 있다
(주로 베이스 클래스로 사용)
한 개의 클래스에 여러 개를 사용할 수 있다한 개의 클래스에 여러 개를 사용할 수 없다.
구현 객체의 같은 동작을 보장하기 위한 목적상속을 받아서 기능을 확장시키는 데 목적

좀 더 정리가 필요한 부분들이 많습니다. 추가적인 업로드 필요


http://loustler.io/languages/oop_interface_and_abstract_class/

결과적으로 자바는 call by value입니다. C/C++과 같이 주소값을 직접 사용하는 것이 아닌, 복사해서 사용합니다.


반면, C/C++은 call by reference로 값을 전달할 경우 주소 자체가 전달됩니다.


C++
#include 
using namespace std;

class Student{
public:
    int age;
public:
    Student(int age) : age(age){
    }
     ~Student(){
    }
};

void change(Student &st){
    st = Student(50);
}

int main(){
    Student st(14);
    cout << st.age << endl;
    change(st);
    cout << st.age << endl;
    return 0;
}


출력>>

14

50


JAVA


class Student{
    int age;
    Student(int age){
     this.age=age;
 }
}

public class Test {
 public static void change(Student user) {
     user = new Student(50);
 }

 public static void main(String[] args) {
     Student st = new Student(14);
     System.out.println(st.age);
     change(st);
     System.out.println(st.age);
 }
}


출력>>

14

14


http://www.m2sj.info/entry/%EC%9E%90%EB%B0%94-%EC%9E%90%EB%B0%94%EB%8A%94-%ED%95%AD%EC%83%81-Call-By-Value-%EC%9D%B4%EB%8B%A4


http://gall.dcinside.com/board/view/?id=programming&no=891104&page=3&search_pos=&s_type=search_all&s_keyword=si

※Primitive Type


Primitive Type은 JavaVM에서 지원하는 비객체형 타입입니다. 비객체라는 건 자바에서 사용되는 객체형 타입은 아니지만 예외적으로 지원을 해야하는

기본형 타입을 말하는 것입니다. byte, int, shot, long, integer, float, double, 부동소수점 개열과 boolean등을 예로 들 수 있습니다.


Reference Type


Reference Type은 java에서의 최상위 클래스인 java.lang.Object클래스를 상속하는 모든 클래스들을 말합니다. 물론 new로 인하여 생성하는 것들을

메모리 영역 heap영역에 생성을 하게되고, Garbage collecto라는 곳에 등록을 하게되고 버려집니다.


http://inetizenseo.tistory.com/12

+ Recent posts