[HTML5] 데이터 스토리지



HTML5 학습 참고 사이트
W3School :  http://www.w3schools.com


웹브라우저 클라이언트 단에 사용자에게 편리한 기능을 제공하기 위해 데이터를 저장해야 할 경우가 있다.
예를  들어  쇼핑몰 사이트에서 로그인을 하지 않아도, 쇼핑을 하고 상품을 담아둘 수 있는 장바구니 기능을 생각해보자. 
장바구니에 담긴 상품들은 웹브라우저를 종료하고 나중에 다시 쇼핑물을 다시 방문했을 때도 상품항목이 남아있어서 
사용자는 편리하게 이어서 쇼핑을 할 수 있다. 

만일 매번 방문할 때마다 사용자의 쇼핑상품이 삭제되어 버린다면 상당히 번거로울 것이다. 이처럼 사용자에 기호 등과 
관련된 정보를 웹브라우저 클라이언트에 저장을 하면 사용자에게 편리한 기능을 제공할 수 있다.  이러한 요구사항을 
만족하기 위한 데이터 스토리지 메커니즘을 이 포스트에서 소개하겠다. 

Cookie를 사용하는  방식이 오래전부터 사용되어 왔으며,  HTML5에서는 쿠키의 단점을 보완하기 위해 웹 스토리지 API 와
웹SQL 데이터베이스 API를 제공한다. 이에 대해서 알아보자. 



1. Cookie
Netscape 사에서 개발했으며, 단순히 key와 value의 데이터쌍을 저장하는 텍스트 파일이다.  
Cookie 를 구성하는 데이터에는 name-value, expiry date, Domain and Path 가 있다 그 의미는 다음과 같다. 
name-value 
모든 쿠키는 name-value 쌍을 구성되며, 쿠키의 이름(name)을 통해 정보(value)를 읽을 수 있다. 

expiry date
쿠키가 폐기되는 유효기간. 명시하지 않으면 브라우저를 닫을 때 폐기된다. 만료일은 UTC(표준시)로 설정되야 한다. 

Domain and Path
도메인은 브라우저가 쿠키를 보낼 도메인 주소를 의미하며, Path는 쿠키를 활성화되는 도메인의 디렉토리를 지정한다. 

 쿠키는 자바스크립트 상에서 document.cookie 속성을 통해 접근할 수 있다.  아래의 코드를 보자. 

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=/'

쿠키값을 설정할 때는 위에서와 같이 정해직 포맷에 맞춰  설정해야 한다.  순서는 다음과 같다. 

1 먼저 name-value 쌍을 설정한다
2 다음 세미콜론; 과 공백이 온다
3 다음으로 적절한 형식으로 만료일이 온다. 
4 다시 세미콜론과 공백이 온다
5 다음 path가 온다 

위의 예제에서 ppkcookie2의 값은 이전 쿠키값을 덮어 씌우지 않고 추가된다는 것에 주목하자. 

쿠키를 삭제하기 위해서는 오늘 날짜 이전으로 만료일을 설정하면 브라우저가 만료됐음을 확인하고 삭제한다. 
document.cookie 값 설정시 만료일을 -1로 설정하면 쿠키값이 즉시 삭제되며,  0으로 설정하면 브라우저를 닫을 때
삭제된다. 




2. 웹 스토리지

엄청나게 발전한 쿠키라고 생각할 수 있으며,  쿠키와 비슷하게 name=value 쌍으로 데이터를 저장한다. 
도메인당 최대 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를 사용해서 객체를 텍스트화하여
저장하고 다시 텍스트를 객체로 복원하는 방식으로 우회하여 사용해야 한다.  

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 데이터베이스는 웹브라우저에 내장된 데이터베이스이며, 대량의 데이터를 관리하기에 유용하다. 
SQL 처리 후 콜백형태로 다음 실행내용을 전달하며 비동기 방식으로 동작하며,   서버가 아닌 로컬 데이터베이스를
사용하기 때문에 커넥션을 맺고 닫는 부분이 없다.  한 도메인에는 동일한 이름을 갖는 DB 버전은 하나만 존재한다. 
(현재  1.0 버전을 사용하는데 같은 이름의 DB가 있을 수 없다는 의미 같다. )
 데이터베이스 작업 간에 트랜잭션을 시작하고 그 콜백으로 SQL문을 수행하는 처리를 한다. 데이터 베이스 크기의
제한은 없지만 일반적으저 브라우저들이 5Mb의 크기로 제한한다. 


브라우저별 웹 SQL 데이터베이스의 지원현황은 아래와 같다. 
아직은 브라우저에서의 지원이 미비하기 때문에, 사용시 반드시 지원유무를 확인하는 처리를 해야한다는 것에 주의하자. 





데이터베이스를 조작하는 코드는 아래와 같다. 


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);   
  }
});

function(tx,error) 함수는 transaction 실패시 실행되는 에러처리 함수로 옵션사항이다. 별도의 에러처리를 하지 않아도
된다면 명시하지 않아도 된다. 
또 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(‘’); 
			}
		});
	});
}


위 SQL문에서 strftime(string format time) 함수는 sqlite 의 함수로 포맷팅 문자열에 맞게 날짜를 출려하는 함수이다. 
위 코드에서는 amount가 all 아니면 현재시간(now)에서 amount 분만큼을 뺀 값을 1970-01-01 이후 경과한 초(%s)로 나타내고있다.

다음 링크에서 함수에 대한 설명을 참고하자 :  SQLite

 


데이터 조회시에는 다음과 같은 속성을 사용할 수 있다.

insertId :  삽입시에만 사용
rowAffected : select 조회시에는 이 값은 0임
rows : 컬렉션. rows 객체를 사용해
results.rows.item(i).screen_name 형태로 필드값을 가져올 수 있음. 
results.rows.length 로 컬렉션의 길이를 알수 있음. 




 
 

'언어로그 > 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 소개



1. HTML (Hyper Text Markup Language)
문서가 서로 다른 OS에서 동일한 형식으로 보여지게 하기위한 필요성에 의해 등장했으면, SGML 이란 마크업 언어를
원류로 하고 있다.


2. HTML의 구성
<head> 와 같은 눈에 보이지 않는 요소 와 <table>. <div>와 같은 눈에 보이는 요소 로 나뉜다
눈에 보이는 요소는 다시 block-levelinline-level 로 구분된다.
 block-level 은 <div>와 같이 한라인에 하나만 위치할 수 있는 요소이고,
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>

 block-level 요소는 inline-level 요소를 포함할 수 있지만, 그 반대는 불가능하다 .



2.1 block-level elements
p               - 문단태그
h1~h6        - 글씨 태그
ul              - 도형목록 태그
ol              - 순서목록 태그
pre            - 공백까지 그대로 출력
dl                
div             - 영역을 지정해줌
noscript       
blockquote 
form           
hr                - 수평선을 그려줌
table
fieldset
address


2.2 inline-level elements
samp
kbd
var
cite
abbr
acronym
a                  - 링크
img               - 이미지
object
br
script
map
q
sub
sup
span
bdo
input
select
textarea
label
button



 2.3 table 태그
사이트에 레이아웃을 잡는데 활용되며, 중첩해서 사용할 수 있다.
 
<table border=1 width="700" height="400">
 <tr>
     <td height="10%">상단</td>
 </tr>

 <tr>
     <td height="80%" width="100%">
     <table border=1 height="100%" width="100%" >
             <tr>
               <td> 테스트 1</td>
               <td> 테스트 2</td>
            </tr>
        </table>
        </td>
    </tr>

<tr>
   <td height="10%">하단</td>
</tr>
</table>


2.4 table 선을 단선으로 표현하기 : border-collapse
table에 border 속성을 주면 2중 선으로 테투리가 그려지는데, style 속성으로 border-collapse:collapse 를 줘서 단선으로 그릴수 있다.
 
  <table width="90%" cellpadding="5" cellspacing="0" border="1" align="center" style="border-collapse:collapse;border:1px gray solid;">
  <tr>
   <td style="border:1px gray solid;">Css </td>
   <td style="border:1px gray solid;">Cascading Style Sheet</td>
  </tr>
 </table>


2.5 table 셀 크기 고정하기 : table-layout 속성
 table 태그에 한글을 쓰면 중간중간 공백이 들아가기 때문에 테이블의 width에 맞춰 자동 줄바꿈이 된다.
그러나 공백이 없는 영문 주소와 같은경우,  width 를 지정해줘도 밀리는 경우가 생긴다.
이때 table 태그 style 속성에 style="table-layout:fixed" 를 지정해서 밀리는 것을 방지할 수 있다. 
그러나 이럴경우, width 를 넘어서는 부분은 내용이 잘리는데, word-break:break-all 속성으로  width에 맞춰
줄바꿈하게 해줄 수 있다.
 
 
<!--  한글은 공백으로 인해 자동 줄바꿈 -->
  <table width="200" cellpadding="5" cellspacing="2" border="1" align="center">
  <tr>
   <td> 셀안의 데이터가 한글인 경우 지정한 셀의 크기에 따라서 자연스럽게 줄바꿈이 일어납니다.</td>  
  </tr>
  </table>
  
  <!-- 공백이 없는 영문주소는 width를 지정해도 셀이 측면으로 밀림 -->
  <table width="200" cellpadding="5" cellspacing="2" border="1" align="center">
  <tr>
   <td>http://www.homejjang.com/09/border-callapse.php</td>  
  </tr>
  </table>
  <!-- table-layout:fixed 를 설정해서 셀 크기 고정 : 하지만 내용이  잘린다. -->
  <table width="200" cellpadding="5" cellspacing="2" border="1" align="center" style="table-layout: fixed;">
  <tr>
   <td>http://www.homejjang.com/09/border_collapse.php</td>
  </tr>
  </table>
  <!-- word-break:break-all; 지정해서 width에 맞춰  줄바꿈이 일어나게 함   -->
  <table width="200" cellpadding="5" cellspacing="2" border="1" align="center" style="table-layout:fixed; word-break:break-all;">
  <tr>
   <td>http://www.homejjang.com/09/border_collapse.php</td>
  </tr>
  </table>

'언어로그 > 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++ 2011. 6. 13. 23:08



#1. 윤년구하기 
사용자에게 년도를 입력받아 윤년인지 아닌지를 판단하는 프로그램을 작성.
단, 하나의 1f~else 문을 이용하여 작성.
        윤년의 조건
4로 나누어 떨어지는 해
그 중에서 100으로 나누어 떨어지는 해는 평년
하지만 400으로 나누어 떨어지는 해는 윤년

1_empty_year.c


#2. 삼각형과 역삼각형 출력
선택 및 반복문을 이용하여 작성
임의 숫자를 입력받아 삼각형과 역삼각형 출력

결과


2_triangles.c


#3. 다이아몬드  출력
선택 및 반복문을 이용하여 작성
임의 숫자를 입력받아 삼각형과 역삼각형 출력

결과


3_diamond.c


#4. 다이아몬드  테두리 출력
선택 및 반복문을 이용하여 작성
임의 숫자를 입력받아 삼각형과 역삼각형 출력

결과


4_diamond_border.c


#5. 알파벳 출력
메뉴번호를 입력하면,  각 문자열 도형 출력.
정수 65부터 90까지가 ASCII A-Z 임.

결과




5_alphabet_chars.c


과제 #1 입출력,연산자

언어로그/C/C++ 2011. 6. 13. 23:01



#1 온도변환 : 화씨, 섭씨
화씨 온도(F)를 입력 받은 후 섭씨 온도(C)로 계산하여 출력하는 프로그램
C = 5/ 9 * (F -32)

화씨 온도를 입력하세요 : 85
섭씨 온도는 29.4도 입니다.

1_temperature.c


#2 원의 넓이 구하기
사용자 입력으로 원의 반지르을 입력받고, 원의 넓이를 구하는 프로그램
원의 넓이 = 반지름 * 반지름 * 3.14159

원의 반지름을 입력하세요 : 10.5
원의 면적 346.36

2_circle_breadth.c


 
#3 신체질량지수(BMI)
몸무게와 키를 입력받고, 신체질량지수(BMI)를 구하는 프로그램 작성. BMI는 비만도를 측정하는 한가지 방법.
BMI = 몸무게(kg) / 키(m)의 제곱

몸무게를 입력하세요( kg) : 62
키를 입력하세요(m) : 1.75
당신의 BMI는 : 20.2입니다.

3_bmi.c


#4 거리 및 속력계산
거리(km)와 속력(km/h)을 입력받고, 해당 거리를 속력으로 달릴 때 걸리는 시간 출력 프로그램 작성.
거리, 속력은 실수. 시간은 시간, 분까지 계산 출력. 초는 소수점 이하 셋째 자리까지 출력

거리(km)을 입력하세요 : 100
속력(km/h)을 입력하세요 : 85

걸리는 시간은 : 1시간, 10분, 35.294초 입니다 

4_velocity.c


#5 자판기 잔돈계산
커피 자판기에 입력받은 돈으로 거스름돈 계산 하는 프로그램 작성
커피 값은 150원
지폐는 1000단위만 입력가능.
거스름 돈은 500원, 100원, 50원, 10원.
자판기가 내주는 동전의 종류와 수를 계산하시오

돈을 입력하세요 : 1000

잔돈 드릴게요 ..
500원짜리 동전 1개
100원짜리 동전 3개
 50원짜리 동전 1개
 10원짜리 동전 0개

5_vending_machine.c

음수의 표현

언어로그/C/C++ 2011. 6. 13. 22:53


컴퓨터에서는 모든 데이터들이 이진수로 표현된다.  어떻게 데이터들이 표현되는지 아는 것은 
때로는 효율적인, 때로는 효과적으로 프로그래밍하기 위해 필수적인 요소이다.  
문제가 발생하는 몇 가지 다른  음수의 비트 표현에 대해서 알아보자. 


부호화 비트 표현법
가장 단순하게 음수를 표현하는 방법으로부호화비트 표현법이 있다.  가장 상위 비트를 부호비트로 표현하여
부호비트가 0이면 양수, 1이면 음수로 표현하는 방법이다.  하지만 두 수를 연산하는데 문제가 생기게 되는데...

4비트로 수를 표현하되 첫번째 비트가 부호비트라고 가정해보자
  + 5        =>     0101    
 -  5        =>     1101  (부호화 비트 표현)
  와 같이 +5는 0101,  -5는 부호비트만 바꾼 1010 으로 표현이 된다.
 하지만 두 값을 더한 값은 0이 되야 하지만 결과는 0010 (2)가 되어 잘못된 결과가 나오게 된다. 



1의 보수 표현법
그래서 다른 이진수 음수 표현법이 필요하게 됐고, 1의 보수표현법, 2의 보수표현법이 생겨나게 됐다.
 
1의 보수표현법은 음수를,  절대값의 이진수 표현에서 각 비트를 역전 시킨 값을 음수로 나타낸다.  
+ 5      =>     0101
 - 5      =>     1010   (1의 보수 표현 )
두 값 0101과 1010을 더하면 결과는 1111 이 나온다.  음수를 1의 보수로 변경했기 때문에
다시 결과를 1의 보수로로 취해주면 결과는 0000이 되어 올바른 결과가 나온다. 




2의 보수 표현법
그럼 2의 보수 표현법을 알아보자. 2의 보수 표현법은 1의 보수표현법에 1을 더한 값이다 
+ 5     =>      0101
 - 5     =>      1011  (2의 보수 표현)
두 값 0101 과 1011 을 더하면 10000이 나오고, 4비트 표현이기 때문에 최상위 1비트를 버리면,
결과가 0으로 올바른 값이 나온다.

2의 보수표현법은 1의 보수 표현법보다 속도가 더 빠르기 때문에 (총 n비트라면 1의 보수표현법은 2n번의 비트 역전을,
2의 보수표현법은 1n + 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

문자열 조작함수 직접 구현하기

언어로그/C/C++ 2011. 4. 29. 14:41



API를 이해하기 위한 가장 좋은 방법 중 하나는  직접 구현해보는 것이다 
 string.h  에서 지원하는  문자열 조작 함수들을 직접 구현해보았다.  이 함수들은 이름에 'str' 이라는 접두어를
가지고 있는데 직접 구현한 버전에는 "my_" 라는 접두어를 붙혔다. 




1. 문자열 함수들의 프로토 선언과 기능
 
  1. // 문자열 s의 길이를 반환하는 함수
  2. int strlen(char *s);      


    // s에 문자열 t를 복사하는 함수

  3. void strcpy(char *s, char *t);

  4. // 두 문자열을 비교하는 함수 : 같으면 0, 앞문자열이 크면 양수, 작으면 음수반환
  5. int strcmp(char *s, char *t);

  6. // 문자열 dest의 끝에 src 문자열을 연결하는 함수

  7. char *strcat(char *dest, const char *src)

  8. // 문자열 string에서 문자 c를 찾아 위치를 반환하는 함수. 없으면 NULL 반환
  9. char *strchr(const char *string, int c);

  10. // 문자열 string의 끝에서부터 문자 c를 찾아 위치를 반환하는 함수. 없으면 NULL 반환
  11. char *strrchr(const char *string, int c);

  12. // 문자열 string에서 문자열 strSearch를 찾아 첫번째 위치를 반환. 없으면 NULL 반환
  13. char *strstr(const char *string, const char *strSearch);

  14. // 문자열 string에서 strCharSet문자열에 속한 문자가 발견되면 그 위치를 반환. 없으면 NULL 반환
  15. char *strpbrk(const char *string, const char *strCharSet);

  16. //  문자열 str에서  delims 문자열에 속한 문자를 구분자로 분리해주는 함수. 첫번째 호출후
  17. //  NULL 을 주어 호출하면, 기존 문자열에서 계속 구분자를 기준으로 분리해서 반환해줌// 원 문자열을 변경하기 때문에 원치않다면 원문자열의 복사본을 사용해야 한다.
  18. char *strtok(char *str, const char *delims);




2. 문자열 조작 함수의 구현

my_string.c

#include <stdio.h>
#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 *= 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 (; *== *t; s++, t++) {
        if (*== '\0') {
            return 0;
        }
    }
    return *- *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
  • 근혜 2016.11.21 03:52 ADDR 수정/삭제 답글

    strstr함수 문제가있는거같아요~ 확인해보세요

    • 로그 @로그 2016.12.07 11:08 신고 수정/삭제

      전체 문자열이 일치하는 경우 예외사항이 발생하고 있네요. ^^ 해당 케이스 수정했습니다. 감사합니다.

Inner Class(내부 클래스)

언어로그/Java 2011. 4. 12. 00:16



 오래전에 Inner Class  개념을 공부하면서  "Thinking In Java 4/e"  을 바탕으로 정리한 내용이다. 

1. 외곽클래스의 멤버메서드(static이 아닌)에서는 내부클래스의 객체를 다른 클래스 객체처럼 참조할 수 있다.

2. 외곽클래스의 static메서드에서는 반드시 '외곽클래스명.' 통해 내부클래스 객체를 참조할 수 있다

3. 내부 클래스 내부에서는 외곽클래스의 멤버를 자유롭게 참조할 수 있는데, 이것은 내부클래스가 자신을 생성한
    외곽클래스 객체의 참조를 은밀히 가지고 있기 때문이다. 내부클래스 객체 내부에서 '외곽클래스명.this'를 사용하여
    접근할 수 있다.

4.  내부클래스 객체 생성시, 특정 외곽클래스 객체와 연결하고자 할때(앞서 외곽클래스 this참조를 은밀히 갖느다고 했다)에는,
    해당 외곽클래스 객체에 대한 참조를 '.new'키워드에 지정해야 한다

5. 지역내부 클래스(local inner class)는 외곽클래스 멤버메서드 내부 또는 코드블록({}로 둘러싸인)에서 정의되고,  
   객체가 생성되는 것이다.  지역내부 클래스를 사용하는 이유는,
   (1) 특정인터페이스를 구현하는 내부 클래스의 객체를 생성후, 그 참조를 반환시거나,
   (2) 클래스의 접근을 일정범위 내로 제한하고자 할때

 6. 내부 클래스 왜 필요할까?
   내부클래스는 다중상속의 문제점을 해결하는 하나의 방안이다. 여러개의 인터페이스를 구현해서, 다중상속을 구현하지만,
    여전히 하나의 추상클래스 밖에 상속하지 못하기 때문에 제한이 있다. 이를 해결하는 것이 내부클래스로, 특정 클래스를
    내부클래스가 상속하게 하여 보다쉽게 다중상속의 기능을 제공하게 된다.

7. 이벤트 중심 시스템(Event Driven System)과 같은 제어 프레임워크의 구현에서, 내부클래스가 많이 사용된다.
   내부클래스를 사용한 제어 프레임워크의 한가지 예제 코드는 다음과 같다.


이벤트 기반 제어프레임워크 소스 예


이벤트를 정의하는 추상클래스 (어떠한 액션을 캡슐화한다)




이벤트를 큐에 쌓고, 순차적으로 실행시키는 컨트롤러 (이벤트들의 행위를 순차적으로 실행한다)




이벤트 추상클래스를 상속하는 구현 이벤트 클래스들 (구체적인 액션 대한 정의)
(불을 켜고, 끄고 벨을 누르고, 프로그램을 종료하는 이벤트들을 내부클래스를 사용해서 정의하였다.)




프로그램을 실행시키는  entry-point  클래스 



컬렉션(Collection)

언어로그/Java 2011. 4. 11. 23:26



자바에서는 효율적인 데이터 처리를 위해 일련의 컨테이너 자료구조 라이브러리를 제공하고 있다.  데이터를 담는다는
의미에서 컨테이너라고 하며,  최상위 추상클래스 Collection의 이름을 따서 컬렉션이라고 부르기도 한다. 
데이터를 다루는 방법과 데이터에 대한 조작 연산(CRUD)의 빈도에 따라 최적화되어 있는 다양한 자료구조들을 제공하고 있다. 
이 컬렉션의 클래스들에 대한 모두 기억할 필요는 없다.  데이터 추가/조회/수정/삭제 중 어떤 연산이 많은 빈도를 가지고 있는지에 따라 어떤 컬렉션 클래스가 적합한지 알고 사용하면 되겠다.  각 컬렉션들에 대한 구체적인 설명은 생략하겠다. 
컬렉션류 클래스들의 전체 상속도는 다음과 같다







컬렉션 클래스들 중 Set 과 HashMap 대한 특성을 알아보자. 



1. Set
기본형 타입 외 사용자 정의타입에 대해 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() 을 모두 재정의 하는 것이 바람직한 습관이다. 




2. Map
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());
                }
        }
}



실행결과


리플렉션으로 Getter 와 Setter 검사하기

언어로그/Java 2011. 4. 7. 20:35


리플렉션을 사용하여 해당 클래스가 어떤 getter와 setter를 갖는지 검사하는 예를 알아보자.


클래스에 getter와 setter 메서드만을 검사할 수는 없으며,  모든 메서드들을  스캔하여 getter인지 setter인지를 확인해야 한다.
getter와 setter 메서드가 나타내는 특성은 다음과 같다. 

Getter 는  “get” 이라는 이름으로 시작하며, 파라미터가 없고 하나의 값을 반환한다.
Setter 는  “set” 이라는 이름으로 시작하며, 하나의 파라미터를 취한다. 

몇몇 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) 사용하기

언어로그/Java 2011. 4. 7. 19:53



지난 포스팅에 이어 리플렉션을 사용하여 객체를 생성하고, private 필드에 접근하는 방법 그리고  메서드를 호출하는
방법에 대해 알아보자.



1. 리플렉션을 사용하여 객체생성
리플렉션을 사용하여 런타임에 클래스에 생성자들을 검사하고,  생성자 객체를 통해 객체를 생성하는 과정을 알아보자.
아래와 같이 3가지 단계를 거치게 되며 가장 먼저 클래스의 생성자 객체  java.lang.reflect.Consturctor 를 얻어야 한다. 


1.1  Constructor 객체 획득하기
다음과 같이 Class 객체로부터 Constructor 클래스를 얻는다. 
// 생성자 목록 얻기 
Class aClass = ... // 이전에 얻은 클래스 객체
Constructor[] constructors = aClass.getConstructors();


Constructor[] 배열은 클래스에 선언된 모든 public 생성자의 Constructor 인스턴스를 가집니다.  특정한 파라미터를 갖는
특정한 생성자는 다음과 같이 얻을 수 있다. 
// 특정 파라미터를 갖는 생성자 얻기 
Class aClass = ... // 이전에 얻은 클래스 객체
Constructor constructor =
        aClass.getConstructor(new Class[]{String.class});


위 예는 하나의 String 타입 파라미터를 갖는 생성자를 반환하는데, 일치하는 파라미터를 갖는 생성자가 없으면 
NoSuchMethodException 예외가 발생한다.


1.2 Constructor 파라미터 얻기  
 다음과 같이 생성자에 포함된 파라미터 타입 목록을 얻을 수 있다.
// 생성자의 파라미터 타입목록 얻기
Class aClass = ... // 이전에 얻은 클래스 객체
Class[] parameterTypes = constructor.getParameterTypes();


1.3 Constructor 객체를 사용하여 객체 생성하기
다음과 같이 생성자 객체로부터 객체를 생성한다. 
// 하나의 String 파라미터를 갖는 생성자를 얻는다. 
Constructor constructor = MyObject.class.getConstructor(String.class);
// 생성 
MyObject myObject = (MyObject)constructor.newInstance("constructor-arg1");

Constructor.newInstance() 메서드는 선택적인 개수의 파라미터를 취한다.  하지만 반드시 해당 생성자에 맞는 개수와 타입의 
파라미터를 제공해야 한다는 것에 주의하자.
 


 

2. 리플렉션을 사용하여 Field 에 접근하기
리플렉션을 사용하여 클래스의 모든 멤버 변수를 검사할 수 있으며, 런타임에 값을 얻어오거나 설정할 수 있다.
이때 하나의 프로퍼티 당 하나의 java.lang.reflect.Field 클래스 객체를 사용하게 된다. 

2.1 Field  객체 얻기 
다음과 같이 Field 객체를 얻는다. 
// 클래스에 선언된 public 속성의 Field 객체얻기
Class aClass = ... // 이전에 얻은 클래스 객체
Field[] fields = aClass.getFields();


Field[] 배열은  클래스에 선언된 각 public field  당 하나의 Field 객체를 갖는다.(public field 만을 갖는다는 것에 주의)
접근하려는 필드의 이름을 안다면,  다음과 같이 접근할 수  있다. 
// Field에 접근하기 
Class  aClass = MyObject.class
Field field = aClass.getField("someField");


위 예제는 아래 MyObject 에 선언된 someField 에 대응하는 Field 인스턴스를 반환합니다. 
public class MyObject{
  public String someField = null;
}

 getField() 메서드의 파라미터에 해당하는 이름의 필드가 클래스에 존재하지 않으면  NoSuchFieldException 예외가 발생한다.


2.2 Field 이름 얻기 
Field 인스턴스를 획득하면, 다음과 같이 Field.getName()을 사용하여 이름을 얻을 수 있다.
// Field 이름 얻기
Field field = ... // Field 객체를 얻는다. 
String fieldName = field.getName();


2.3 Field  타입 얻기
Field.getType() 메서드를 사용하여 필드의 타입을 얻을 수 있다. 
// Field 타입 얻기 
Field field = aClass.getField("someField");
Object fieldType = field.getType();


2.4 Field 값 조회하고 설정하기 
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을 전달한다.
 
  
2.5 Private Field 에 접근하기 
클래스의 Private 필드는 외부클래스에서 접근 할 수 없지만,  리플렉션을 사용하면 접근이 가능하다.  캡슐화를 깨는 동작일 
수 있지만, 단위테스트와 하이버네이트와 같은 프레임워크에서 유용하게 사용되기도 한다. 
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 예외가 발생한다. 





3. 리플렉션을 사용하여 Method 호출하기
 java.lang.reflect.Method 클래스를 사용하여  메서드를 검사하고 호출 하는 방법을 알아보자.



3.1 Method 객체 얻기  
Method 클래스를 다음과 같이 획득한다.  
// Method 객체목록 얻기 
Class aClass = ... // 이전에 얻은 클래스 객체
Method[] methods = aClass.getMethods();


역시 클래스에 선언된 public 메서드당 하나의 Method 인스턴스를 갖으며, 메서드의 구체적인 파라미터 타입들을 알고 있으면
해당 메서드의 인스턴스를 얻을 수 있다. 다음은 String 파라미터 하나를 갖는 doSomething 메소드의 Method 객체를 얻는다.
// 파라미터를 갖는 메소드의 Method 객체 얻기 
Class aClass = ... // 이전에 얻은 클래스 객체
Method method = aClass.getMethod("doSomething", new Class[]{String.class});


만일 일치하는 메서드가 없으면, NoSuchMethodException이 발생한다. 파라미터가 없는 메서드를 얻기 위해서는 파라미터
배열 대신 null을 전달한다.
// 파라미터가 없는 메서드의 Method 객체 얻기 
Class aClass = ... // 이전에 얻은 클래스 객체
Method method = aClass.getMethod("doSomething", null);



3.2 Method 파라미터와 반환값 얻기
다음과 같이 해당 메서드의 파라미터들을 얻을 수 있다.
// 메서드의 파라미터 타입목록 얻기 
Method method = ... //
Class[] parameterTypes = method.getParameterTypes();

메서드의 반환타입은 다음과 같이 접근한다.
// 메서드의 반환값 타입 얻기 
Method method = ... //
Class returnType = method.getReturnType();



3.3  Method 객체를 사용하여 메서드 호출하기(Invoking)
다음과 같이 메서드를 호출할 수 있다.
// 메서드 호출 
Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(null, "parameter-value1");

invoke() 메소드에는 호출하기를 원하는 객체를 전달하며, static 메서드이면 null을 대신 전달한다.
Method.invoke(Object target, Object...parameters) 메서드는 선택적인 개수의 파라미터를 취하지만,  메서드가 필요로 하는
정확한 개수의 파라미터를 전달해야 한다. 


3.4 Private Method 에 접근하기 
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