[Java] 어노테이션 사용하기

언어로그/Java 2011. 3. 19. 23:38



Annotation을 실제로 사용하는 예제를 알아보자.  

첫번째 예제는 UseCase라는 어노테이션을 정의한다. 이 어노테이션은 id와  description이라는 값을
멤버로 갖으며 각각 기능번호와 기능에 대한설명을 나타낸다.  Password 검사와 관련된 클래스에스는 각 메소드에 
UseCase 어노테이션을 사용하여 메서드들이 어떤 유스케이스를 구현하고 있는지를 표시한다. 
나중에 모든 유스케이스를 구현하는 모든 메소드들이 잘 구현되었는지 확인하기 위해  UseCaseTracker 를 사용하여 
어노테이션 정보를 출력한다. (코드는 Thinking in Java 4E 에 있는 예제코드를 사용하였다. )


1. UseCase 어노테이션 정의
메서드에 사용할 어노테이션이므로 @Target을 ElementType.METHOD를 설정하였고, 
 런타임 시에 사용되기 때문에 @Rention을 RetentionPolicy.RUNTIME 로 설정하여 class 파일에 어노테이션 정보가 남도록
지정하였다. 
package net.atgame.annotation.usecase;

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
	public int id();
	public String description() default "no description";
}



2. PasswordUtil 클래스에 정의한  어노테이션을 사용한다. 
UseCase 어노테이션은 코드 작성간에는 주석의 역할을 하고,  코드 실행시에는 테스트로서의 역할도 한다.
import java.util.List;

public class PasswordUtils {
	
	@UseCase(id = 47, description = "passwords must contain at least one numeric")
	public boolean validatePassword(String password) {
		return (password.matches("\\w*\\d\\w*"));
	}
	
	@UseCase(id = 48)
	public String encryptPassword(String password) {
		return new StringBuilder(password).reverse().toString();
	}
	
	@UseCase(id = 49, description = "New passwords can't equal perviously used ones")
	public boolean checkForNewPassword(List prevPasswords, String password) {
		return !prevPasswords.contains(password);
	}
}




3.  UseCaseTracker를 사용하여 모든 유스케이스를 구현하는 메소드들이 작성되었는지 확인한다. 

아래 코드에서는 리플렉션을 사용하여 유스케이스 아이디 47, 48, 49, 50 을 사용하는 메소드들을 검색하여 
그 메서드의 어노테이션 멤버를  출력하고 있다.  이 프로그램 실행을 통해 어떤 유스케이스가 아직 구현되지 
않았는지 알 수 있다. 
package net.atgame.annotation.usecase;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class UseCaseTracker {
	
	public static void trackUseCases(List useCases, Class cl) {
		for (Method m : cl.getDeclaredMethods()) {
			UseCase uc = m.getAnnotation(UseCase.class);
			if (uc != null) {
				System.out.println("Found Use Case:" + uc.id() + " " + uc.description());
				useCases.remove(new Integer(uc.id()));
			}
		}
		
		for (int i : useCases) {
			System.out.println("Warning: Missing use case~" + i);
		}
	}
	
	public static void main(String[] args) {
		List useCases = new ArrayList();
		Collections.addAll(useCases, 47, 48, 49, 50);
		trackUseCases(useCases, PasswordUtils.class);
	}
}

어노테이션이 어떻게 정의되고 사용되는지 보여주기 위해 위 예제를 사용하였다. 어노테이션(UserCase)을 정의를 했다면, 
그 어노테이션을 처리하기 위한 클래스(UseCaseTracker)도 반드시 작성해야함을 눈여겨보자.












 이제 좀더 실용적인 두번째 예제를 소개하겠다.  데이터베이스 접속 처리를 하기위해 데이터베이스 종류에 맞는 
SQL을 작성하여 DBMS에 전송해야한다.  데이터베이스에 맞는 SQL 작성! 이 상당히 코드를 지저분하게 만들수 있기 때문에
모듈화가 잘 고려되어야 한다. 데이터베이스별 SQL 작성을 안할 수는 없지만  어노테이션을 사용하면, DB 접속에 관한 부분을
클라이언트 프로그래머에게 투명하게 처리할 수 있다. 그 의미에 대해서 알아보자 


1. 테이블명을 나타내기 위한 DBTable 어노테이션을 정의한다. 
package net.atgame.annotation.database;

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
	public String name() default "";
}


2. 테이블 컬럼의 타입을 나타내기 위한 SQLInteger 와 SQLString 어노테이션을 정의한다. 
package net.atgame.annotation.database;

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 SQLInteger {
	String name() default "";
	Constraints constraints() default @Constraints;
}



3. 제약조건을 나타내기 위한 Constraint 어노테이션을 정의한다.
package net.atgame.annotation.database;

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 SQLString {
	int value() default 0;
	String name() default "";
	Constraints constraints() default @Constraints;
}



4. Memeber 모델 클래스에 정의한 어노테이션들을 사용한다. 
package net.atgame.annotation.database;

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 Constraints {
	boolean primaryKey() default false;
	boolean allowNull() default true;
	boolean unique() default false;
}



5. TableCreator 클래스에서 어노테이션 정보를 사용하여, 데이베이스 생성 SQL를 만들어낸다. 
package net.atgame.annotation.database;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class TableCreator {
	
	public static void main(String[] args) throws Exception {
		if (args.length < 1) {
			System.out.println("arguments: annotated classes");
			System.exit(0);
		}
		// 모든 엔티티 클래스를 읽음 
		for (String className : args) {
			Class cl = Class.forName(className);
			// 클래스 어노테이션 가져오기 
			DBTable dbTable = cl.getAnnotation(DBTable.class);
			if (dbTable == null) {
				System.out.println("No DBTable annotations in class " + className);
				continue;
			}
			String tableName = dbTable.name();
			
			if (tableName.length() < 1) {
				tableName = cl.getName().toUpperCase();
			}
			List columnDefs = new ArrayList();
			
			/// 필드목록 조회 
			for (Field field : cl.getDeclaredFields()) {
				String columnName = null;
				Annotation[] anns = field.getDeclaredAnnotations();
				if (anns.length < 1) {
					continue;
				}
				if (anns[0] instanceof SQLInteger)  {
					SQLInteger sInt = (SQLInteger)anns[0];
					if (sInt.name().length() < 1) {
						columnName = field.getName().toUpperCase();
					} else {
						columnName = sInt.name();
					}
					columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints()));
				}
				if (anns[0] instanceof SQLString) {
					SQLString sString = (SQLString)anns[0];
					if (sString.name().length() < 1) {
						columnName = field.getName().toUpperCase();
					} else {
						columnName = sString.name();
					}
					columnDefs.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints()));
				}
				
			}
			StringBuilder createCommand = new StringBuilder("CREATE TABLE " + tableName + " (");
			for (String columnDef : columnDefs) {
				createCommand.append("\n " + columnDef + ",");
			}
			// 마지막 쉼표제거 
			String tableCreate = createCommand.substring(0, createCommand.length()-1) + ");";
			System.out.println("Table Creation SQL for " + className + " is :\n" + tableCreate);
		}
		
	}
	
	private static String getConstraints(Constraints con) {
		String constraints = "";
		if (!con.allowNull()) {
			constraints += " NOT NULL";
		}
		if (con.primaryKey()) {
			constraints += " PRIMARY KEY";
		}
		if (con.unique()) {
			constraints += " UNIQUE";
		}
		return constraints;
	}
}



어노테이션을 읽어 데이터베이스 SQL을 생성하는 부분에 주목하자. 
Model 클래스 어노테이션 정보를 읽어서 DB에 해당하는 SQL를 생성하고, 테이블을 생성하게 할 수 있다.  
더 나아가 getter 와 setter 메소드를 오버라이드하여 인스턴스에 대한 조작만으로 데이터베이스 CRUD(등록,조회,수정,삭제)
연산을 처리하게 할 수도 있을 것이다. 이렇게 하면 데이터베이스 종류에 따른 번거로운 처리를 클라이언트 프로그래머에게
좀더 투명하게 사용할 수 있다. 


이상 어노테이션을 사용하는 예제를 간략히 알아보았다. 어노테이션을 잘 활용하면 간결하고, 투명한 코드를 작성할 수 있다.
 하지만 언제나 그렇듯 "잘 활용하면" 이라는 조건이 붙는다.  어떻게 잘 활용할지에 대한 생각은 이제 개인의 몫이다.
 

'언어로그 > Java' 카테고리의 다른 글

(2) 리플렉션(Reflection) 사용하기  (0) 2011.04.07
(1) 리플렉션(Reflection)  (3) 2011.04.07
예외처리 (Exception Handling)  (0) 2011.03.24
[Java] 어노테이션 사용하기  (1) 2011.03.19
[Java] 어노테이션(Annotation)  (2) 2011.03.15
[자바] (1) 자바소개  (0) 2011.03.10
  • 장곰부대 2018.06.12 09:20 신고 ADDR 수정/삭제 답글

    안녕하세요 블로그 글 잘보고 있습니다.

    궁금한 점이 있어서 질문 드려봅니다.

    마지막 코드 약 22번째 줄에서
    String tableName = dbTable.name();
    if(tableName.length() < 1) {
    tableName = c1.getName().toUpperCase();
    }
    이걸 왜하는 건지 궁금합니다.
    아예 처음부터
    tableName = c1.getName() 이런식으로 처리하면 안됩니까?

[Java] 어노테이션(Annotation)

언어로그/Java 2011. 3. 15. 01:40



프로그래밍을 하면서 @Override 와 @Test와 같은 어노테이션들을 많이 사용했지만,  그 중요성이나 의미를 
깊이 있게 생각해보지는 못했었다.  단순히 컴파일러에게 알려주기 위한 표식정도로 생각했었다.  그런데  Spring Roo 와 
Spring3.0 과 같은 최신 프레임웍들의 변화 경향을 보면,  어노테이션을 적극활용하는 쪽으로 변화되고 있다.  어노테이션을
사용하여 코드의 작성량도 한결 줄어들었다고 한다.  어노테이션들의 어떤 특성을 활용한 것일까?  어노테이션이란 뭘까?
최신 프레임웍들에 변화경향을 보기에 앞서, 어노테이션에 대해서 먼저 알아보았다.



1. Annotation 이란?
Annotation은 JEE5 부터 새롭게 추가된 문법요소이다.  사전적으로는 "주석"이라는  의미를 가지고 있으며, 의미대로
자바 코드에 주석처럼 달아 특수한 의미를 부여해준다.   이 특별한 의미는 컴파일 타임 또는 런타임에 해석될 수 있다.
 

 

2.  기존 웹애플리케이션들의 문제점
기존의 자바 웹애플리케이션들은 선언적인 프로그래밍 방식을 사용한다.  선언적이란  프로그램의 전체 및 각 레이어별
구성과 설정값들을 외부의 XML 설정파일에 명시하는 방식을 의미한다.  변경이 될 수 있는 데이터들을 최대한 코드가 아닌
외부설정파일에 분리하기 때문에 변경 요구사항이 들어왔을 때, 재컴파일 없이도 쉽게 변경사항을 적용할 수 가 있다. 
유연성이란 장점을 얻었지만,  단점 또한 존재한다. 프로그램 작성을 위해 매번 많은 설정파일을 작성해야 한다는 것이다. 
그 규모가 커질수록 설정의 양도 많아지게 되며 이를 잘 구조화 할 수 있는 방법도 필요하게 된다. 또 하나의 단점은 이것보다
좀 더 크다.   도메인 데이터 처리정보가 Model 클래스, 서비스 클래스,  XML 설정파일에 분산되어 있어서,   이를 확인하기
위해서는 Model , Service 클래스와 XML 설정파일을 모두 뒤져야 한다는 것이다. 




3. Annotation의 사용했을 때의 장점은? 
어노테이션을 사용하면 위와 같은 문제를 해결 할 수 있다.  데이터에 대한 유효성 검사조건을 어노테이션을 사용하여
Model 클래스에 직접 명시함으로써 해당 데이터들에 대한 유효조건을 쉽게 파악할수 있게되며, 코드의 양도 줄어든다.
(엄밀히 말하면,  코드의 양은 줄어들지 않는다. 하지만 코드가 깔끔해지고, 어노테이션의 재사용도 가능해진다. )



4. 그렇다면 XML 설정은 사용하지 않아야 하는가?
앞서 말했다시피, XML은 유연성을 확보해준다.   어노테이션을 사용하여 한번 빌드된 코드는 수정을 위해서는 
재컴파일 해야하는 단점이 있다.  애플리케이션 전체적인 설정이나 디플로이 환경에 따라 변경되는 사항들은 XML 설정을
사용하자.  각각의 장단점을 파악하고, 언제 무엇을 사용해야할지 아는 것이 중요하다. 


그럼 이제부터 어노테이션을 사용해보자. 사용을 위해 먼저 선행지식들에 대해 잠깐 알아보자. 


5. 일반적인  어노테이션의 용도 
어노테이션은 크게 ① 문서화 ② 컴파일러 체크 ③ 코드 분석을 위한 용도로 사용된다.  문법적으로는 @기호가 
붙은 심볼을 사용하며 패키지, 클래스, 메소드,  프로퍼티, 변수에 명시할 수 있다. 이 어노테이션이 붙은 소스를 
컴파일 시에 수집하여 API 문서화 할수도 있지만 기존에 JavaDoc 라는 좋은 문서화 도구가 있기 때문에 "문서화" 는 
가장 비중이 낮은 어노테이션의 사용법이다. 
또한 컴파일 타임에 에러를 발생시켜 주어 개발자에서 위험요소를 경고해주거나 확인하는 목적으로도 사용된다. 
가장 큰 비중을 갖는 것은 코드 분석 또는 "메타-데이터" 로서의 용도이다. 메타-데이터 란 데이터를 위한 데이터, 즉 
데이터에 대해 설명하는 데이터를 의미한다.  메타데이터로서 어노테이션의 효용을 가장 잘 느낄 수 있는 부분이
JEE 설정과 유효성 검사 부분이다. 



5.  어노테이션의 분류
어노테이션은 메타데이터 저장을 위해 클래스처럼 멤버를 갖을 수 있다. 이 멤버의 개수에 따라 Marker 어노테이션,
Single-value,  Full 어노테이션으로 분류할 수 있다. 


①  Marker 어노테이션
     - 멤버 변수가 없으며, 단순히 표식으로서 사용되는 어노테이션이다. 컴파일러에게 어떤 의미를 전달한다. 

②  Single-value  어노테이션
    - 멤버로 단일변수만을 갖는 어노테이션이다. 단일변수 밖에 없기 때문에 (값)만을 명시하여 데이터를 전달할 수 있다.  

 Full 어노테이션
    -멤버로 둘 이상의 변수를 갖는 어노테이션으로, 데이터를 (값=쌍)의 형태로 전달한다. 




6.  빌트인(Built-in) 어노테이션 
자바 SDK에서 지원하는 어노테이션으로 @Override, @Deprecated, @SupressWarning 등이 있다. 



@Override 
 어노테이션은 현재 메소드가 수퍼클래스의 메소드를 오버라이드한 메소드임을 컴파일러에게 명시한다. 만일
수퍼 클래스에 해당하는 메소드가 없으면 컴파일러가 인지하고 에러를 발생시켜 준다. 

 

@Deprecated 

 마커 어노테이션으로  차후 버전에 지원되지 않을 수 있기 때문에 더 이상 사용되지  말아야할 메소드를 나타낸다.  

 특이하게 더이상 사용되지 말아야할 메소드와 같은 라인상에 놓여져야 한다. (이유모름)

(두 플래그  -deprecated 또는 Xlint:deprecated 중 하나와 javac 명령어를 사용하여 컴파일러 경고를  켜야만, 

 컴파일러 에러를 발생시켜준다)

@SupressWarning
의미데로 경고를 제거하는 어노테이션이다. Object형을 엘리먼트로 하는 컬렉션을 사용하면,  컴파일러 경고가 발생하는데
이 어노테이션을 사용하여 프로그래머의 의도적인 Object 형 사용임을 알려 경고를 제거할 수 있다. 




7. 커스텀(Custom) 어노테이션 

클래스와 같이 어노테이션을 임의로 정의하여 사용할 수 있다. 어노테이션은 interface 키워드 앞에 @를 붙여 표시한다. 


1) 커스텀 어노테이션 정의하 



// 메소드와 클래스가 여전히 작업중임을 나타내기 위해 정의한 마커 어노테이션
public @interface InProgress { }

어노테이션 정의파일을 컴파일하고, 이 파일을 클래스패스에서 참조할 수 있으면 다른 소스코드상에서 어노테이션을

사용할 수 있다. 



2) 멤버 추가하기 

어노테이션 유형은 멤버변수를 가질 수 있으며, 이 변수들  컴파일시 또는 런타임에 메타-데이터로서 사용될 수 있다.  
이렇게 정의를 하면 자동으로 
accessor와 mutator를 제공해준다.


// 해당 태스크가 완료되야함 나타내는 어노테이션

public @interface TODO {

  String value();           

}


정의한 어노테이션을 다음과 같이 사용한다. 


@TODO("Figure out the amount of interest per month")

public void calculateInterest(float amount, float rate) {

  // ...

}


단일 멤버를 갖을 경우에만 위와 같이 사용할 수 있다. 



3) 디폴트 값 설정하기 
 

public @interface GroupTODO {


  public enum Severity { CRITICAL, IMPORTANT, TRIVIAL, DOCUMENTATION };


  Severity severity() default Severity.IMPORTANT;

  String item();

  String assignedTo();

  String dateAssigned();

}


디폴트값을 사용한 예는 다음과 같다. 

@GroupTODO(

    item="Figure out the amount of interest per month",

    assignedTo="Brett McLaughlin",

    dateAssigned="08/04/2004"

  )

  public  void calculateInterest(float amount, float rate) {

    // ...

  }





4
) 메타-어노테이션

어노테이션에 사용되는 어노테이션으로 해당 어노테이션의 동작대상 및 보여타임을 결정한다. 


① @Target 메타-어노테이션

   어노테이션이 적용되는 동작 프로그래밍 

엘리멘트를 지정하며, 다음과 같은 값들이 있다. 

package java.lang.annotation;


public enum ElementType {

  TYPE,       // Class, Interface, enum 

  FIELD,                       // 프로퍼티 (enum 나열값들은 제외)

  METHOD,       // 메서드

  PARAMETER,       // 메서드 파라미터

  CONSTRUCTOR,                     // 생성자

  LOCAL_VARIABLE,       // 로컬변수 또는 Catch문

  ANNOTATION_TYPE,       //  어노테이션(메타 어노테이션)_

  PACKAGE       //  자바 패키지

}




② @Retention 메타-어노테이션 

     자바컴파일러가 어노테이션을 다루는 방법과 관련이 있다.  소스파일, 클래스파일, 런타임 중 어느시점까지

    어노테이션을 보유하고 있을 것인지를 결정한다. 


package java.lang.annotation;


public enum RetentionPolicy {

  SOURCE, // 어노테이션이 컴파일러에 의해 버려짐

  CLASS, // 어노테이션이 클래스파일에 저장되지만, JVM에게 무시됨

  RUNTIME // 어노테이션이 클래스파일에 저장되며, JVM에 의해 읽혀짐 

}

 

위 세값 중 하나를 인자로 취해 다음과 같이 사용된다. 


@Retention(RetentionPolicy.SOURCE)

public @interface SuppressWarnings {

  ...

}






'언어로그 > Java' 카테고리의 다른 글

(2) 리플렉션(Reflection) 사용하기  (0) 2011.04.07
(1) 리플렉션(Reflection)  (3) 2011.04.07
예외처리 (Exception Handling)  (0) 2011.03.24
[Java] 어노테이션 사용하기  (1) 2011.03.19
[Java] 어노테이션(Annotation)  (2) 2011.03.15
[자바] (1) 자바소개  (0) 2011.03.10
  • alecsander 2012.05.30 13:05 ADDR 수정/삭제 답글

    좋은 자료 감사합니다^^ 담아가요~

  • 반가 2016.06.09 12:59 ADDR 수정/삭제 답글

    좋은 정보 잘보고 갑니다

[자바] (1) 자바소개

언어로그/Java 2011. 3. 10. 00:49


나름 잘 보이게 한다고, 노란박스를 사용했는데...굉장히 눈을 자극하네요...otz...   


자바(Java)란?

자바언어의 개발사인 썬은 spac이란 서버제품군을 제작하는 회사였는데, 낮은 H/W 마진을 개선하고자, 자사의 H/W 위에 마진이 높은 SW(유닉스 등)를 얹혀 팔려했는데, H/W 마다 SW를 재작성해야하는 문제가 있었습니다.  이에 해결책으로 , 즉 한번 작성하면  다양한 머신 위에서  동일하게 작동할 수 있는 SW를 작성할 수 있는  java를 개발하게 된겁니다.


자바의 장정

객체지향적이고, 플래폼 독립적이고, 동적이고 배포하기 쉬우며, 견고하고 보안에 강하다고 합니다.

엄밀히 말하면 객체지향적이다는 특성은 전적으로 S/W를 작성하는 개발자에게 달려있습니다.

 

                                       

플랫폼 독립성

c언어와 같이 컴파일러가 머신에 의존적인 기계어 코드(실행파일)를  생성하면, 유닉스, 리눅스, 윈도우, 맥 등 각 머신에서 소스를  재컴파일 해야합니다. (각 머신에 맡는 바이너리를 생성해야함).  반면 자바는 OS  와 소스 사이에 Java Virtual Machine이라는 중간계층을 두어 이를 해결했습니다. 소스코드를 가상머신이 인식할 수 있는 중간언어인 바이트 코드로 컴파일해서 배포하는 겁니다. 그러면 각 OS에 설치되있는, JVM이 바이트코드를 머신 의존적인 기계어 코드로 번역하여 실행하는 겁니다. 

 (단,  OS마다 각 머신에 맞는 JVM을 설치해야하지만, 한번만 설치하면 이후에는 소스를 재컴파일 해야하는 번거로움이 사라집니다. 바이너리 레벨에서의 플랫폼 독립성을 확보하게 됩니다. )  



기업 인터넷 환경에서 자바

유연성을 위해  3 - tier ( 프레젠테이션 계층 - 비지니스 계층 - 데이터(DB) 계층 ) 의 형태로 구성된답니다.

현재는 더욱 확장된 N - tier로  됩니다.  

          


JVM(Java Virtual Machine)의 동작방식

클래스 로더는 먼저 소스코드를 보고 모든 필요한 클래스를 로드합니다. 필요한 클래스 위치는 CLASSPATH 환경변수를 참조하여 해당하는 위치에서 찾게됩니다. JVM Verifier는 오작동을  일으킬 수 있는 코드(무한루프)를 검사해 실행을 차단하고, 이어 바이트 코드를 실행합니다. 또한 Just-In-Time 컴파일러를 호출하여, 소스코드와 클래스 파일을 비교합니다. 클래스 파일이 생성되지 않았거나, 소스코드가 클래스파일보다 나중에 수정됐을 때만 재컴파일을  합니다.

(JIT 를 도입해서 자바의 느린성능을 어느 정도 극복했고, 버전업 될때마다, 개선을 통해 성능을 향상시키고 있습니다.)

가비지 컬레터라는 메모리 관리자는  더 이상 사용되지 않는 객체를 수시로 검사하여 자동으로 메모리를 반환해줍니다.



자바환경에서의 보안

언어차원 - 컴파일러 - 클래스 로더 - bytecode verifyer 등 계층적으로 위해한 코드를 차단해주어 안정성을 제공합니다.

자바애플리케이션은  - .zip 또는 .jar로  형태로 압축하여 배포합니다. .jar은 단순히 소스만 압축 할 수도 있고,  클래스파일

까지 포함하여 같이 압축해서 실행가능한 형태로 만들수 있습니다. 웹 기반 애플리케이션은  .WAR 형태로 압축해서 배포

합니다.



JDK(Java Development Kit)

보통 J2SE(Java2 Standard Edition)를 의미하며, 자바를 기반으로 SW를 개발할 수 있는 환경을 의미합니다.  

컴파일러(javac),  core class 라이브러리, 디버거(jdb), JVM, JAR(Java ARchive utility), 기타 등으로 구성됩니다.

Java1.2 버전 이후 부터 대폭 내부구조가 개선되었으며, 이런 변경을 표현하기 위해 1.2 버전 이후부터는 JAVA2라고 

부릅니다. 개발 아키텍처에 따라 J2SE, J2ME, J2EE 로 나뉘기도 합니다.  J2ME는 모발일 환경  SW 작성을 위해 꼭 필요한 

핵심 클래스만으로 이루어진 버전입니다. J2EE는 기업환경에 적합하게 병렬실행 등을 강화한 버전입니다. 


'언어로그 > Java' 카테고리의 다른 글

(2) 리플렉션(Reflection) 사용하기  (0) 2011.04.07
(1) 리플렉션(Reflection)  (3) 2011.04.07
예외처리 (Exception Handling)  (0) 2011.03.24
[Java] 어노테이션 사용하기  (1) 2011.03.19
[Java] 어노테이션(Annotation)  (2) 2011.03.15
[자바] (1) 자바소개  (0) 2011.03.10