검색결과 리스트
언어로그에 해당되는 글 48건
- 2011.06.26 [HTML5] 데이터 스토리지
- 2011.06.13 HTML 소개
- 2011.06.13 과제 #2 제어문/선택문을 이용해 다양한 모양그리기
- 2011.06.13 과제 #1 입출력,연산자
- 2011.06.13 음수의 표현
- 2011.04.29 문자열 조작함수 직접 구현하기 (2)
- 2011.04.12 Inner Class(내부 클래스)
- 2011.04.11 컬렉션(Collection)
- 2011.04.07 리플렉션으로 Getter 와 Setter 검사하기
- 2011.04.07 (2) 리플렉션(Reflection) 사용하기
글
[HTML5] 데이터 스토리지
HTML5 학습 참고 사이트
W3School : http://www.w3schools.com
예를 들어 쇼핑몰 사이트에서 로그인을 하지 않아도, 쇼핑을 하고 상품을 담아둘 수 있는 장바구니 기능을 생각해보자.
장바구니에 담긴 상품들은 웹브라우저를 종료하고 나중에 다시 쇼핑물을 다시 방문했을 때도 상품항목이 남아있어서
사용자는 편리하게 이어서 쇼핑을 할 수 있다.
만일 매번 방문할 때마다 사용자의 쇼핑상품이 삭제되어 버린다면 상당히 번거로울 것이다. 이처럼 사용자에 기호 등과
관련된 정보를 웹브라우저 클라이언트에 저장을 하면 사용자에게 편리한 기능을 제공할 수 있다. 이러한 요구사항을
만족하기 위한 데이터 스토리지 메커니즘을 이 포스트에서 소개하겠다.
Cookie를 사용하는 방식이 오래전부터 사용되어 왔으며, HTML5에서는 쿠키의 단점을 보완하기 위해 웹 스토리지 API 와
웹SQL 데이터베이스 API를 제공한다. 이에 대해서 알아보자.
1. Cookie
Cookie 를 구성하는 데이터에는 name-value, expiry date, Domain and Path 가 있다 그 의미는 다음과 같다.
모든 쿠키는 name-value 쌍을 구성되며, 쿠키의 이름(name)을 통해 정보(value)를 읽을 수 있다.
expiry date
쿠키가 폐기되는 유효기간. 명시하지 않으면 브라우저를 닫을 때 폐기된다. 만료일은 UTC(표준시)로 설정되야 한다.
Domain and Path
도메인은 브라우저가 쿠키를 보낼 도메인 주소를 의미하며, Path는 쿠키를 활성화되는 도메인의 디렉토리를 지정한다.
document.cookie = 'ppkcookie1=testcookie; expires=Thu, 2 Aug 2001 20:47:11 UTC; path=/' document.cookie = 'ppkcookie2=another test; expires=Fri, 3 Aug 2001 20:47:11 UTC; path=/'
쿠키값을 설정할 때는 위에서와 같이 정해직 포맷에 맞춰 설정해야 한다. 순서는 다음과 같다.
쿠키를 삭제하기 위해서는 오늘 날짜 이전으로 만료일을 설정하면 브라우저가 만료됐음을 확인하고 삭제한다.
document.cookie 값 설정시 만료일을 -1로 설정하면 쿠키값이 즉시 삭제되며, 0으로 설정하면 브라우저를 닫을 때
삭제된다.
2. 웹 스토리지
도메인당 최대 5Mb 를 지원하며 sessionStorage, localStorage 를 제공한다. sessionStorage는 브라우저가 닫히기까지(세션)
동안 유효하며, localStorage 는 명시적으로 데이터를 지우지 않는 한 계속 남아있게 된다.
브라우저별 웹스토리지 지원현황은 아래와 같이 최신버전의 브라우저 모두에서 지원하는 기능이다.
스토리지 API를 사용할 수 있다고 한다. 그래서 쿠키를 사용가능한지 사전에 검사해야 한다.
쿠키가 가용한지 검사하는 코드는 아래와 같이 쿠키를 하나 생성하고 값 읽기를 시도해봐서 가용한지를 확인할 수 있다.
var cookieEnabled = (function() {
var id = new Date().getTime();
document.cookie = 'cookieprobe=' + id + ' ;path=/';
return (document.cookie.indexOf(id) != -1);
})();
웹 스토리지 API 형태는 다음과 같다.
속성 unsigned int length 메소드 DOMString key(unsigned int index) any getItem(DOMString key) void setItem(DOMString key, data) void removeItem(DOMString key) void clear()
데이터 저장 및 조회
sessionStorage.setItem(‘twitter’, ‘@rem’); sessionStorage.twitter = ‘@rem’; sessionStorage.getItem(‘cost’); sessionStorage.twitter
key 메소드 사용
for (var i = 0; i < sessionStorage.length; i++) {
alert(sessionStorage.key(i) + ‘=’ + sessionStorage.getItem(sessionStorage.key(i)));
}
removeItem 과 clear 함수를 사용할 수 있다. removeItem 은 지정한 key에 해당하는 아이템을 삭제하며, clear 함수는 모든
아이템을 삭제한다.
문자열 이외 저장
저장하고 다시 텍스트를 객체로 복원하는 방식으로 우회하여 사용해야 한다.
JSON를 사용하여 객체화하고 복원하는 코드는 다음과 같다.
function stringify() {
var videoDetails = {
author: '감우성',
description: '무법자',
rating: '5.51'
};
sessionStorage.setItem('videoDetails', JSON.stringify(videoDetails));
}
function parse() {
var videoDetails = JSON.parse(sessionStorage.getItem('videoDetails') || 'null');
alert(videoDetails.author + "\n" + videoDetails.description + "\n" + videoDetails.rating);
}
3. 웹 SQL 데이터베이스
SQL 처리 후 콜백형태로 다음 실행내용을 전달하며 비동기 방식으로 동작하며, 서버가 아닌 로컬 데이터베이스를
사용하기 때문에 커넥션을 맺고 닫는 부분이 없다. 한 도메인에는 동일한 이름을 갖는 DB 버전은 하나만 존재한다.
(현재 1.0 버전을 사용하는데 같은 이름의 DB가 있을 수 없다는 의미 같다. )
데이터베이스 작업 간에 트랜잭션을 시작하고 그 콜백으로 SQL문을 수행하는 처리를 한다. 데이터 베이스 크기의
제한은 없지만 일반적으저 브라우저들이 5Mb의 크기로 제한한다.
아직은 브라우저에서의 지원이 미비하기 때문에, 사용시 반드시 지원유무를 확인하는 처리를 해야한다는 것에 주의하자.
데이터베이스를 조작하는 코드는 아래와 같다.
DB 생성 및 Open / API 지원유무 확인하기
var db;
if (window.openDatabase) {
db = openDatabase(‘mydb’, ‘1.0’, ‘My first database’, 2 * 1024 * 1024);
}
openDatabase의 인자는 DB이름, 버전, DB에 대한 설명, DB 의 크기이다.위 코드에서는 mydb 라는 이름의 2MB(2 * 1024 * 1024) 데이터베이스를 생성하였고,
window.openDatabase 속성을 확인하여 웹SQL 데이터베이스 API를 지원하는지 확인했다.
SQL 실행
db.transaction(
function(tx) {
tx.executeSql(sql, [], function () {
// 실행코드
});
},
function(tx, error) {
alert(‘에러: ‘ + error.message);
}
});
된다면 명시하지 않아도 된다.
또 executeSql(sql, [], function () {}) 함수는 실제로 SQL을 수행하는 함수로 필수 인자는 실행할 질의문 sql 인자 뿐이다.
[] 는 SQL 의 와일드 카드 문자에 삽입할 파라미터를 담은 배열이며, function()은 SQL 을 수행후 후속 작업을 처리할
함수이다.
var db;
if (window.openDatabase) {
db = openDatabase(‘tweetdb’, ‘1.0’, ‘All my tweets’, 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql(‘CREATE TABLE tweets (id, date, tweet)’); });
}
데이터 삽입하기
function saveTweets(tweets) {
tweets.results.forEach(function (tweet) {
db.transaction(function (tx) {
var time = (new Date(Date.parse(tweet.created_at))).getTime();
tx.executeSql(‘INSERT INTO tweets (id, screen_name, ¬date, text) VALUES (?, ?, ?, ?)’,
[tweet.id, ¬tweet.from_user, time / 1000, tweet.text]);
});
});
}
데이터 조회하기
var tweetEl = document.getElementById(‘tweets’);
function show(amount) {
db.transaction(function (tx) {
tx.executeSql(‘SELECT * FROM tweets’ + (amount != ‘all’ ? ‘ WHERE date > strftime(“%s”, “now”, “-’ + amount + ‘ minutes”)’ : ‘’), [],
function (tx, results) {
var html = [], len = results.rows.length;
for (var i = 0; i < len; i++) {
html.push(‘<li>’ + results.rows.item(i).text + ‘</li>’);
}
tweetEl.innerHTML = html.join(‘’);
}
});
});
}
위 코드에서는 amount가 all 아니면 현재시간(now)에서 amount 분만큼을 뺀 값을 1970-01-01 이후 경과한 초(%s)로 나타내고있다.
다음 링크에서 함수에 대한 설명을 참고하자 : SQLite
데이터 조회시에는 다음과 같은 속성을 사용할 수 있다.
'언어로그 > Html/Javascript/CSS' 카테고리의 다른 글
| HTML5 Canvas API (0) | 2012.03.11 |
|---|---|
| jquery 간략한 사용법 (0) | 2011.10.15 |
| [HTML5] 데이터 스토리지 (0) | 2011.06.26 |
| HTML 소개 (0) | 2011.06.13 |
설정
트랙백
댓글
글
HTML 소개
원류로 하고 있다.
inline-level 은 <span>과 같이 한라인에 복수로 위치할 수 있는 요소이다.
<div style="border:1px gray solid;">block-level element </div> <div style="border:1px gray solid;">block-level element </div> <span style="border:1px gray solid;">inline-level element </span> <span style="border:1px gray solid;">inline-level element </span>
2.4 table 선을 단선으로 표현하기 : border-collapse
'언어로그 > Html/Javascript/CSS' 카테고리의 다른 글
| HTML5 Canvas API (0) | 2012.03.11 |
|---|---|
| jquery 간략한 사용법 (0) | 2011.10.15 |
| [HTML5] 데이터 스토리지 (0) | 2011.06.26 |
| HTML 소개 (0) | 2011.06.13 |
설정
트랙백
댓글
글
과제 #2 제어문/선택문을 이용해 다양한 모양그리기
결과
결과
결과
결과
'언어로그 > C/C++' 카테고리의 다른 글
| [C/C++] C 언어 포스트 목록 (0) | 2015.08.30 |
|---|---|
| 과제 #2 제어문/선택문을 이용해 다양한 모양그리기 (0) | 2011.06.13 |
| 과제 #1 입출력,연산자 (0) | 2011.06.13 |
| 음수의 표현 (0) | 2011.06.13 |
| 문자열 조작함수 직접 구현하기 (2) | 2011.04.29 |
| 라인 입출력 함수 (0) | 2011.03.27 |
설정
트랙백
댓글
글
과제 #1 입출력,연산자
걸리는 시간은 : 1시간, 10분, 35.294초 입니다
'언어로그 > C/C++' 카테고리의 다른 글
| [C/C++] C 언어 포스트 목록 (0) | 2015.08.30 |
|---|---|
| 과제 #2 제어문/선택문을 이용해 다양한 모양그리기 (0) | 2011.06.13 |
| 과제 #1 입출력,연산자 (0) | 2011.06.13 |
| 음수의 표현 (0) | 2011.06.13 |
| 문자열 조작함수 직접 구현하기 (2) | 2011.04.29 |
| 라인 입출력 함수 (0) | 2011.03.27 |
설정
트랙백
댓글
글
음수의 표현
때로는 효율적인, 때로는 효과적으로 프로그래밍하기 위해 필수적인 요소이다.
문제가 발생하는 몇 가지 다른 음수의 비트 표현에 대해서 알아보자.
부호화 비트 표현법
가장 단순하게 음수를 표현하는 방법으로부호화비트 표현법이 있다. 가장 상위 비트를 부호비트로 표현하여
부호비트가 0이면 양수, 1이면 음수로 표현하는 방법이다. 하지만 두 수를 연산하는데 문제가 생기게 되는데...
1의 보수 표현법
2의 보수 표현법
'언어로그 > C/C++' 카테고리의 다른 글
| 과제 #2 제어문/선택문을 이용해 다양한 모양그리기 (0) | 2011.06.13 |
|---|---|
| 과제 #1 입출력,연산자 (0) | 2011.06.13 |
| 음수의 표현 (0) | 2011.06.13 |
| 문자열 조작함수 직접 구현하기 (2) | 2011.04.29 |
| 라인 입출력 함수 (0) | 2011.03.27 |
| 배열의 이해 (0) | 2011.03.27 |
설정
트랙백
댓글
글
문자열 조작함수 직접 구현하기
string.h 에서 지원하는 문자열 조작 함수들을 직접 구현해보았다. 이 함수들은 이름에 'str' 이라는 접두어를
1. 문자열 함수들의 프로토 선언과 기능
- // 문자열 s의 길이를 반환하는 함수
int strlen(char *s);
// s에 문자열 t를 복사하는 함수- void strcpy(char *s, char *t);
- // 두 문자열을 비교하는 함수 : 같으면 0, 앞문자열이 크면 양수, 작으면 음수반환
- int strcmp(char *s, char *t);
// 문자열 dest의 끝에 src 문자열을 연결하는 함수
- char *strcat(char *dest, const char *src)
- // 문자열 string에서 문자 c를 찾아 위치를 반환하는 함수. 없으면 NULL 반환
- char *strchr(const char *string, int c);
- // 문자열 string의 끝에서부터 문자 c를 찾아 위치를 반환하는 함수. 없으면 NULL 반환
- char *strrchr(const char *string, int c);
- // 문자열 string에서 문자열 strSearch를 찾아 첫번째 위치를 반환. 없으면 NULL 반환
- char *strstr(const char *string, const char *strSearch);
- // 문자열 string에서 strCharSet문자열에 속한 문자가 발견되면 그 위치를 반환. 없으면 NULL 반환
- char *strpbrk(const char *string, const char *strCharSet);
- // 문자열 str에서 delims 문자열에 속한 문자를 구분자로 분리해주는 함수. 첫번째 호출후
- // NULL 을 주어 호출하면, 기존 문자열에서 계속 구분자를 기준으로 분리해서 반환해줌// 원 문자열을 변경하기 때문에 원치않다면 원문자열의 복사본을 사용해야 한다.
- char *strtok(char *str, const char *delims);
2. 문자열 조작 함수의 구현
#include <string.h>
int my_strlen(char *s);
void my_strcpy(char *s, char *t);
int my_strcmp(char *s, char *t);
char *my_strcat(char *dest, const char *src);
char *my_strncat(char *dest, const char *src,size_t count);
char *my_strchr(const char *string, int c);
char *my_strrchr(const char *string, int c);
char *my_strstr(const char *string, const char *strSearch);
char *my_strpbrk(const char *string, const char *strCharSet);
char *my_strtok(char *str, const char *delims);
int main (int argc, char const* argv[])
{
char dest[1024] = "nice to meet you!";
char *test = "my name is kimsungbae! what's up?";
char *token;
printf("strchr : %s \n", strchr(test, '!'));
printf("my_strchr: %s \n", my_strchr(test, '!'));
printf("\n");
printf("strrchr : %s \n", strrchr(test, '\''));
printf("my_strrchr: %s \n", my_strchr(test, '\''));
printf("\n");
printf("strstr : %s \n", strstr(test, "is"));
printf("my_strstr: %s \n", my_strstr(test, "is"));
printf("\n");
printf("my_strcat : %s \n", my_strcat(dest, test));
printf("my_strncat: %s \n", my_strncat(dest, "@@@@@@@@", 2));
printf("\n");
printf("strpbrk : %s \n", strpbrk(test, "?!\'"));
printf("my_strpbrk : %s \n", my_strpbrk(test, "?!\'"));
token = my_strtok(dest, " ");
printf("%s \n", token);
while ((token = my_strtok(NULL, " ")) != NULL) {
printf("%s \n", token);
}
return 0;
}
int my_strlen(char *s) {
char *p = s;
while (*p++ != '\0');
return p - s;
}
void my_strcpy(char *s, char *t) {
while (*s++ = *t++) ;
}
int my_strcmp(char *s, char *t) {
for (; *s == *t; s++, t++) {
if (*s == '\0') {
return 0;
}
}
return *s - *t;
}
char *my_strcat(char *dest, const char *src) {
char *p_dest = dest;
while (*p_dest != '\0') {
p_dest++;
}
while (*src != '\0') {
*p_dest++ = *src++;
}
*p_dest = '\0';
return dest;
}
char *my_strncat(char *dest, const char *src,size_t count) {
char *p_dest = dest;
while (*p_dest != '\0') {
p_dest++;
}
while (*src != '\0' && count > 0) {
*p_dest++ = *src++;
count--;
}
*p_dest = '\0';
return dest;
}
char *my_strchr(const char *str, int c) {
while (*str != '\0') {
if (*str == c) {
return str;
}
str++;
}
return NULL;
}
char *my_strrchr(const char *str, int c) {
char *p_str = str + strlen(str) - 1;
while (p_str > str) {
if (*p_str == c) {
return p_str;
}
p_str--;
}
return NULL;
}
char *my_strstr(const char *str, const char *search) {
char *start = NULL;
while (*str != '\0') {
if (start != NULL && *search == '\0') {
break;
}
if (start != NULL && *str != *search) {
start = NULL;
}
if (start == NULL && *str == *search) {
start = str;
}
if (start != NULL && *str == *search) {
search++;
}
str++;
}
return (start != NULL) ? start : NULL;
}
char *my_strpbrk(const char *str, const char *charset) {
char *p_char;
while (*str != '\0') {
p_char = charset;
while (*p_char != '\0') {
if (*str == *p_char++) {
return str;
}
}
str++;
}
return NULL;
}
char *my_strtok(char *str, const char *delims) {
static char *tmp, *pstart;
char *p_delims;
if (str != NULL) {
tmp = str;
}
if (*tmp == '\0') {
return NULL;
}
pstart = tmp;
while (*tmp != '\0') {
p_delims = delims;
while (*p_delims != '\0') {
if (*tmp == *p_delims++) {
*tmp++ = '\0';
return pstart;
}
}
tmp++;
}
return pstart;
}
'언어로그 > C/C++' 카테고리의 다른 글
| 과제 #1 입출력,연산자 (0) | 2011.06.13 |
|---|---|
| 음수의 표현 (0) | 2011.06.13 |
| 문자열 조작함수 직접 구현하기 (2) | 2011.04.29 |
| 라인 입출력 함수 (0) | 2011.03.27 |
| 배열의 이해 (0) | 2011.03.27 |
| 기억부류(Storage Class) / 변수 (0) | 2011.03.27 |
설정
트랙백
댓글
글
Inner Class(내부 클래스)
접근할 수 있다.
객체가 생성되는 것이다. 지역내부 클래스를 사용하는 이유는,
(1) 특정인터페이스를 구현하는 내부 클래스의 객체를 생성후, 그 참조를 반환시거나,
내부클래스가 상속하게 하여 보다쉽게 다중상속의 기능을 제공하게 된다.
이벤트 기반 제어프레임워크 소스 예
이벤트를 정의하는 추상클래스 (어떠한 액션을 캡슐화한다)
이벤트를 큐에 쌓고, 순차적으로 실행시키는 컨트롤러 (이벤트들의 행위를 순차적으로 실행한다)
이벤트 추상클래스를 상속하는 구현 이벤트 클래스들 (구체적인 액션 대한 정의)
(불을 켜고, 끄고 벨을 누르고, 프로그램을 종료하는 이벤트들을 내부클래스를 사용해서 정의하였다.)
프로그램을 실행시키는 entry-point 클래스
'언어로그 > Java' 카테고리의 다른 글
| [java] 라이프 게임 (life game) (1) | 2013.02.03 |
|---|---|
| [java] 제13회 한국자바개발자 컨퍼런스 (0) | 2013.01.30 |
| Inner Class(내부 클래스) (0) | 2011.04.12 |
| 컬렉션(Collection) (0) | 2011.04.11 |
| 리플렉션으로 Getter 와 Setter 검사하기 (0) | 2011.04.07 |
| (2) 리플렉션(Reflection) 사용하기 (0) | 2011.04.07 |
설정
트랙백
댓글
글
컬렉션(Collection)
의미에서 컨테이너라고 하며, 최상위 추상클래스 Collection의 이름을 따서 컬렉션이라고 부르기도 한다.
데이터를 다루는 방법과 데이터에 대한 조작 연산(CRUD)의 빈도에 따라 최적화되어 있는 다양한 자료구조들을 제공하고 있다.
이 컬렉션의 클래스들에 대한 모두 기억할 필요는 없다. 데이터 추가/조회/수정/삭제 중 어떤 연산이 많은 빈도를 가지고 있는지에 따라 어떤 컬렉션 클래스가 적합한지 알고 사용하면 되겠다. 각 컬렉션들에 대한 구체적인 설명은 생략하겠다.
컬렉션류 클래스들의 전체 상속도는 다음과 같다
컬렉션 클래스들 중 Set 과 HashMap 대한 특성을 알아보자.
기본형 타입 외 사용자 정의타입에 대해 Set을 사용하면 데이터들의 중복이 없으며 element 들의 순서를 유지하지 않는다.
(집합과 같이 데이터들의 순서가 중요하지 않으며, 데이터들이 중복없이 하나만 고유하게 존재할 경우 사용한다)
| Set (인터페이스) | 중복요소 저장 안됨. 추가되는 요소는 객체의 동일성 판별을 위해 equals() 메소드를 정의해야함. Collection 과 인터페이스가 동일하며, 요소(element)들의 순서유지가 보장되지 않음. |
| HashSet | 빠른 검색이 가능한 Set. 요소는 equals(), hashCode()를 정의해야함. |
| TreeSet | 트리형태의 순서를 갖는 Set. 정렬된 요소를 얻을 수 있으며, Comparable 인터페이스를 구현해야 함. |
| LinkedHashSet | HashSet의 빠른 검색속도를 갖으며, 내부적으로 LinkedList의 순서를 유지함. 추가된 순서대로 요소를 얻을 수 있음. hashCode() 메소드 또한 정의해야함. |
Set을 사용자 정의 타입에서(클래스에) 사용하려면, 중복성 회피를 위해 equals() 메소드를 재정의 해주어야한다.
(Set는 내부적으로 element 들의 equals() 메소드를 호출하여 서로간의 중복 여부를 판단하기 때문이다)
hashCode()는 hashSet, LinkedHashSet 를 사용할 때만 재정의 해주면 된다. 재정의를 하지 않으면, Object의 hashCode()를
사용하는데, equals()를 구현했어도 객체가 중복되어 Set 인터페이스 규약이 깨지게 된다. (서로 동일한 데이터를 가지고 있어도hashCode()를 구현하지 않으면 다른 버킷으로 해싱되기 때문 데이터가 중복될수 있다. 이것은 Set의 규약을 위반한 것임)
hashCode(), equals() 을 모두 재정의 하는 것이 바람직한 습관이다.
key-value 관계를 저장하여 key를 사용한 value의 검색을 가능하게 함.
| HashMap | 해시 테이블에 기초한 구현 클래스. 객체 추가 / 검색어에 동일한 시간을 보장함. |
| LinkedHashMap | HashMap과 동일한 저장방식을 사용함. 이터레이터를 사용함. key-value 쌍이 추가된 순서, 최근 최소 사용한 빈도에 따른 검색이 가능 HashMap 에 비해 다소 느리고, 순차검색시 내부적으로 연결리스트를 사용해 더빠른 성능을 발휨. |
| TreeMap | 이진 트리에 기초한 맵 구현클래스. key-value 쌍은 Comparable, Comparator에 의해 정렬순서가 저장됨. 하위 트리를 반환하는 subMap() 메소드를 보유함. |
| WeakHashMap | 더 이상 참조되지 않은 key에 대한 가비지 컬렉션을 허용함. |
| ConcurrentHashMap | 동기화에서 락을 발생시키지 않는 Thread-Safe한 Map. |
| IdentityHashMap | key 비교시 equals()가 아닌 == 사용함. 범용사용은 불가능함. |
예제
import java.util.*;
// 모든 Set 컬렉션은
// 중복 회피를 위해 equals()를 재정의 해야함
class SetType {
int i;
public SetType(int n) {
i = n;
}
public boolean equals(Object o) {
return o instanceof SetType && (i == ((SetType)o).i);
}
public String toString() {
return Integer.toString(i);
}
}
// HashSet 계열은 equals() 외에 hasCode()를 재정의 해야함
// 그렇지 않을 경우 equals()를 정의했어도, 데이터 중복이 발생
class HashType extends SetType {
public HashType(int n) {
super(n);
}
public int hashCode() {
return i;
}
}
// TreeSet 계열은 equals() 외에 compareTo()를 재정의 해야함
// compareTo()를 재정의 하지않으면 실행시 ClassCastException 발생
class TreeType extends SetType implements Comparable<treetype>
{
public TreeType(int n) {
super(n);
}
public int compareTo(TreeType arg) {
return (i > arg.i ? 1 : (i == arg.i) ? 0 : -1);
}
}
public class TypesForSets {
static <t> Set<t> fill(Set<t> set, Class<t> type) {
try {
for (int i = 0; i < 10; i++) {
// int형 인자를 갖는 생성자를 얻어서, 객체 생성
set.add(type.getConstructor(int.class).newInstance(i));
}
} catch(Exception e) {
throw new RuntimeException(e);
}
return set;
}
static <t> void test(Set<t> set, Class<t> type) {
// 객체 중복저장 시도 - 셋의 특성을 알아보기 위함
fill(set, type);
fill(set, type);
fill(set, type);
System.out.println(set);
}
public static void main(String[] args) {
// HashSet 계열은 equals() 와 hashCode()를 재정의 해야함
test(new HashSet(), HashType.class);
test(new LinkedHashSet(), HashType.class);
// TreeSet 계열은 equals() 와 compareTo()를 재정의 해야함
test(new TreeSet(), TreeType.class);
// 아래메소드들은 각 Set 컬렉션의 특성이 파괴됨
test(new HashSet(), SetType.class);
test(new HashSet(), TreeType.class);
test(new LinkedHashSet(), SetType.class);
test(new LinkedHashSet(), TreeType.class);
try {
test(new TreeSet(), SetType.class);
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
test(new TreeSet(), HashType.class);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
'언어로그 > Java' 카테고리의 다른 글
| [java] 제13회 한국자바개발자 컨퍼런스 (0) | 2013.01.30 |
|---|---|
| Inner Class(내부 클래스) (0) | 2011.04.12 |
| 컬렉션(Collection) (0) | 2011.04.11 |
| 리플렉션으로 Getter 와 Setter 검사하기 (0) | 2011.04.07 |
| (2) 리플렉션(Reflection) 사용하기 (0) | 2011.04.07 |
| (1) 리플렉션(Reflection) (3) | 2011.04.07 |
설정
트랙백
댓글
글
리플렉션으로 Getter 와 Setter 검사하기
클래스에 getter와 setter 메서드만을 검사할 수는 없으며, 모든 메서드들을 스캔하여 getter인지 setter인지를 확인해야 한다.
몇몇 setter는 값을 반환하지 않을 수도 있고 또 어떤 것은 집합값을 반환하거나 어떤 것들은 메서드 chaining을 위해
값을 반환할 수 있기 때문에 setter의 반환타입에 대한 가정을 해서는 안된다.
다음은 getter와 setter를 찾아 출력하는 예이다.
package com.tistory.hiddenviewer.reflection.executor; import java.lang.reflect.Method; import com.tistory.hiddenviewer.reflection.Board; public class GetterSetterPrinter { public static void main(String[] args) { printGettersSetters(Board.class); } public static void printGettersSetters(Class aClass){ Method[] methods = aClass.getMethods(); for(Method method : methods){ if(isGetter(method)) { System.out.println("getter: " + method); } if(isSetter(method)) { System.out.println("setter: " + method); } } // for } public static boolean isGetter(Method method){ // get 으로 시작하지 않으면 반환 if(!method.getName().startsWith("get")) { return false; } // 파라미터가 있으면 반환 if(method.getParameterTypes().length != 0) { return false; } // 반환값이 없으면 반환 if(void.class.equals(method.getReturnType())) { return false; } return true; }
public static boolean isSetter(Method method){ // set 으로 시작하지 않으면 반환 if(!method.getName().startsWith("set")) { return false; } // 파라미터가 개수가 1이 아니면 반환 if(method.getParameterTypes().length != 1) { return false; } return true; } }
출력결과
'언어로그 > Java' 카테고리의 다른 글
| Inner Class(내부 클래스) (0) | 2011.04.12 |
|---|---|
| 컬렉션(Collection) (0) | 2011.04.11 |
| 리플렉션으로 Getter 와 Setter 검사하기 (0) | 2011.04.07 |
| (2) 리플렉션(Reflection) 사용하기 (0) | 2011.04.07 |
| (1) 리플렉션(Reflection) (3) | 2011.04.07 |
| 예외처리 (Exception Handling) (0) | 2011.03.24 |
설정
트랙백
댓글
글
(2) 리플렉션(Reflection) 사용하기
방법에 대해 알아보자.
아래와 같이 3가지 단계를 거치게 되며 가장 먼저 클래스의 생성자 객체 java.lang.reflect.Consturctor 를 얻어야 한다.
다음과 같이 Class 객체로부터 Constructor 클래스를 얻는다.
// 생성자 목록 얻기 Class aClass = ... // 이전에 얻은 클래스 객체 Constructor[] constructors = aClass.getConstructors();
Constructor[] 배열은 클래스에 선언된 모든 public 생성자의 Constructor 인스턴스를 가집니다. 특정한 파라미터를 갖는
특정한 생성자는 다음과 같이 얻을 수 있다.
// 특정 파라미터를 갖는 생성자 얻기
Class aClass = ... // 이전에 얻은 클래스 객체
Constructor constructor =
aClass.getConstructor(new Class[]{String.class});
위 예는 하나의 String 타입 파라미터를 갖는 생성자를 반환하는데, 일치하는 파라미터를 갖는 생성자가 없으면
NoSuchMethodException 예외가 발생한다.
다음과 같이 생성자에 포함된 파라미터 타입 목록을 얻을 수 있다.
// 생성자의 파라미터 타입목록 얻기 Class aClass = ... // 이전에 얻은 클래스 객체 Class[] parameterTypes = constructor.getParameterTypes();
다음과 같이 생성자 객체로부터 객체를 생성한다.
// 하나의 String 파라미터를 갖는 생성자를 얻는다.
Constructor constructor = MyObject.class.getConstructor(String.class);
// 생성
MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");
Constructor.newInstance() 메서드는 선택적인 개수의 파라미터를 취한다. 하지만 반드시 해당 생성자에 맞는 개수와 타입의
// 클래스에 선언된 public 속성의 Field 객체얻기 Class aClass = ... // 이전에 얻은 클래스 객체 Field[] fields = aClass.getFields();
접근하려는 필드의 이름을 안다면, 다음과 같이 접근할 수 있다.
// Field에 접근하기
Class aClass = MyObject.class
Field field = aClass.getField("someField");
public class MyObject{
public String someField = null;
}
getField() 메서드의 파라미터에 해당하는 이름의 필드가 클래스에 존재하지 않으면 NoSuchFieldException 예외가 발생한다.
// Field 이름 얻기 Field field = ... // Field 객체를 얻는다. String fieldName = field.getName();
// Field 타입 얻기
Field field = aClass.getField("someField");
Object fieldType = field.getType();
Field 에 대한 참조를 얻게되면, Field.get(), Field.set() 메소드를 사용하여 값을 얻거나 설정할수 있다.
// Field 값 설정하고 조회하기
Class aClass = MyObject.class
Field field = aClass.getField("someField");
MyObject objectInstance = new MyObject();
Object value = field.get(objectInstance);
field.set(objetInstance, value);
field.get(), set() 메서드에는 해당 필드를 소유하는 객체가 인자로 전달되야 하며 만일 static 필드라면 null을 전달한다.
수 있지만, 단위테스트와 하이버네이트와 같은 프레임워크에서 유용하게 사용되기도 한다.
private 필드에 접근하기 위해서는 Class.getDeclaredField(String name)와 Class.getDeclaredFields() 메서드를 사용한다. (Class.getField(String name) 와 Class.getFields() 메서드는 public 필드만을 반환한다.)
다음은 private field에 접근하는 예이다.
Board board = new Board();
board.setContents("test contents...");
Field field = cls.getDeclaredField("contents");
field.setAccessible(true);
String contents = (String) field.get(board);
System.out.println("Private Contents Field: " + contents);
Field 객체의 setAccessible(true)를 호출하지 않고, private 필드값을 조회하려고 하면 IllegalAccessException 예외가 발생한다.
// Method 객체목록 얻기 Class aClass = ... // 이전에 얻은 클래스 객체 Method[] methods = aClass.getMethods();
해당 메서드의 인스턴스를 얻을 수 있다. 다음은 String 파라미터 하나를 갖는 doSomething 메소드의 Method 객체를 얻는다.
// 파라미터를 갖는 메소드의 Method 객체 얻기
Class aClass = ... // 이전에 얻은 클래스 객체
Method method = aClass.getMethod("doSomething", new Class[]{String.class});
배열 대신 null을 전달한다.
// 파라미터가 없는 메서드의 Method 객체 얻기
Class aClass = ... // 이전에 얻은 클래스 객체
Method method = aClass.getMethod("doSomething", null);
// 메서드의 파라미터 타입목록 얻기 Method method = ... // Class[] parameterTypes = method.getParameterTypes();
메서드의 반환타입은 다음과 같이 접근한다.
// 메서드의 반환값 타입 얻기 Method method = ... // Class returnType = method.getReturnType();
// 메서드 호출
Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(null, "parameter-value1");
Method.invoke(Object target, Object...parameters) 메서드는 선택적인 개수의 파라미터를 취하지만, 메서드가 필요로 하는
정확한 개수의 파라미터를 전달해야 한다.
Private Field 에 접근하는 것과 유사하게 Class.getDeclaredField(String name)와 Class.getDeclaredFields() 메서드를 사용한다.
(Class.getField(String name) 와 Class.getFields() 메서드는 public 필드만을 반환한다.)
'언어로그 > Java' 카테고리의 다른 글
| 컬렉션(Collection) (0) | 2011.04.11 |
|---|---|
| 리플렉션으로 Getter 와 Setter 검사하기 (0) | 2011.04.07 |
| (2) 리플렉션(Reflection) 사용하기 (0) | 2011.04.07 |
| (1) 리플렉션(Reflection) (3) | 2011.04.07 |
| 예외처리 (Exception Handling) (0) | 2011.03.24 |
| [Java] 어노테이션 사용하기 (1) | 2011.03.19 |
1_empty_year.c