검색결과 리스트
언어로그/Java에 해당되는 글 13건
- 2015.09.03 [java] 글 목록
- 2013.02.16 [Java] 자바란?
- 2013.02.03 [java] 라이프 게임 (life game) (1)
- 2013.01.30 [java] 제13회 한국자바개발자 컨퍼런스
- 2011.04.12 Inner Class(내부 클래스)
- 2011.04.11 컬렉션(Collection)
- 2011.04.07 리플렉션으로 Getter 와 Setter 검사하기
- 2011.04.07 (2) 리플렉션(Reflection) 사용하기
- 2011.04.07 (1) 리플렉션(Reflection) (3)
- 2011.03.24 예외처리 (Exception Handling)
글
[java] 글 목록
JAVA 5
- [Java] 자바란?
- [자바] (1) 자바소개
- 다형성
- 동시성
- 문자열
- 스윙의 기초
- 열거형
- 인터페이스
- 컨테이너
- 클래스 재사용, 상속과 위임
- 프로그램 실행제어
- Assertion
- Exception
- Files
- Graphics
- Inner Class(내부 클래스)
- package
- JCJP6.0
- Serialization
- 리플렉션으로 Getter 와 Setter 검사하기
- (1) 리플렉션(Reflection)
- (2) 리플렉션(Reflection) 사용하기
- 예외처리 (Exception Handling)
- [Java] 어노테이션 사용하기
- [Java] 어노테이션(Annotation)
비트 자바 고급과정
- 컬렉션(Collection)
- Hibernate, AOP
- MVC2, 리다이렉트, 포워드
- SQL
- SQL2
- 게시판 프로그램 변화 과정
- 네트워크, 소켓 프로그래밍
- 다국어 지원, 댓글구현
- 다운로드
- 스트러츠, iBATIS
- 아파치 프로젝트
- 웹서버 설계와 구현
- 이클립스 웹프로젝트 설정
- 자바 IO
- 자바 프로그래밍
- 페이징
- 프레임워크, 스트러츠, 4-layers
- 프레임워크 spring에 통합하기
- 프레임워크 spring에 통합하기. validation 프레임워크
- AJAX
- AjaxLib, DWR
- AspectJ, Tiles, SiteMash
- DWR로 로그인 하기
- EL, JSTL
- HTML1
- HTML2
- HTML3, Javascript
- IBATIS, 게시판, 댓글, 첨부파일, 회원결합
- IBATOR, 검색기능, IBATIS, Dynamic SQL
- JDBC
- JDBC2, SWING
- JDBC Template
- Junit, 단위테스트, 로그인 구현, Spring 프레임워크
- SAX, WAS
- Listener, Filter, AOP
- Servlet, JSP
- Spring과 IBATIS 연동, MultiActionController, SimpleFormController, DWR과 Spring 연동
- Spring 프레임워크, SpringMVC
- SpringMVC2, Spring2
- WAS 구현
- XML
라이프 게임(Life Game)
기타
'언어로그 > Java' 카테고리의 다른 글
| [java] 글 목록 (0) | 2015.09.03 |
|---|---|
| [Java] 자바란? (0) | 2013.02.16 |
| [java] 라이프 게임 (life game) (1) | 2013.02.03 |
| [java] 제13회 한국자바개발자 컨퍼런스 (0) | 2013.01.30 |
| Inner Class(내부 클래스) (0) | 2011.04.12 |
| 컬렉션(Collection) (0) | 2011.04.11 |
설정
트랙백
댓글
글
[Java] 자바란?
벌써 4년전입니다. 2009년도에 비트 자바고급반을 수강하면서 학습한 내용을 Springnote에 꾸준히
정리했습니다. Springnote 서비스가 종료되고, 그 때 백업해 두었던 글들을 하나씩 티스토리로 옮기고
있는데... 열정과 흥미를 가지고 재미있게 공부했었던 그때 기억이 나네요.
2. 자바란?
자바 언어의 개발사인 썬은 spac 이란 서버제품군을 제작하는 회사였습니다.
낮은 H/W 마진을 개선하고자, 자사의 H/W 위에 마진이 높은 S/W(유닉스 등)를 얹혀서 팔려했는데
하드웨어마다 소프트웨어를 재작성해야 하는 문제가 있었습니다. 즉 다양한 머신 위에서
한번작성하면 동일하게 동작하는 S/W를 만들려는 노력해서 Java가 탄생하게 되었습니다
위키: http://en.wikipedia.org/wiki/Java_language
3. 자바의 장점
객체지향적, 플랫폼 독립적, 동적이고 배포하기 쉬우며... 견고하고 보안에 강하다!
하지만 객체지향적이고, 보안에 강하다는 특성을 살리는 것은 소프트웨어를 작성하는 개발자에 전적으로
달려있답니다. (무서운 강사님의 말씀...)
4. 플랫폼 독립적?
c언어는 컴파일러가 머신에 의존적인 기계어 코드(실행파일)를 생성합니다. 유닉스, 리눅스, 윈도우, 맥에서
실행하기 위해서는 소스 수준에서 재컴파일이 필요합니다.
자바는 OS와 소스코드 중간에 JVM(Java Virtual Machine)이라는 중간계층을 두어 이를 해결했습니다.
소스코드를 가산머신이 인식할 수 있는 중간언어인 바이트 코드로 컴파일해서 배포합니다. 그러면 각 OS에
설치되어 있는 JVM이 바이트 코드를 기계어로 번역하여 실행합니다.
(단, 각 OS 마다 각 머신에 맞는 JVM이 설치되어 있어야 합니다. 한번만 설치하면 되니까 매번 소스를
재컴파일해야 하는 것보다는 훨씬 유연성이 있죠)
5. 기업 인터넷 환경에서의 Java
유연성을 위해 3-Tier(프레젠테이션 계층-비지니스 계층-데이터(DB) 계층)의 형태로 구성됩니다.
현재는 더욱 확장된 N-Tier로 구성된다고 하네요.
PS. Three Tier를 삼-Tier로 읽는 센스 ㅋ
6. JVM 의 동작방식
클래스 로더가 소스코드를 스캔하여 모든 필요한 클래스를 로드합니다. 필요한 클래스 위치는 CLASSPATH
환경변수를 참조하게 찾게됩니다. JVM Verifier 가 오작동 될 수 있는 코드(무한루프와 같은...)를 검사해서
사전에 차단합니다. 이어서 바이트 코드를 실행하게 되는데, 이때 JIT(Just-In-Time) 컴파일러가 동작합니다.
즉 소스코드와 (컴파일된 .class)클래스 파일의 수정일자를 비교해서, 소스코드가 더 나중에 수정됐을 경우에만
재컴파일하게 됩니다.
(PS. JIT를 도입해서 자바의 느린 성능을 어느정도 극복했고, 버전업 될때마다 크게 향상되고 있습니다.
또 가비지 컬렉터라는 메모리 관리자가 더이상 사용되지 않는 객체를 수시로 검사하여 자동으로 메모리를
반환해줍니다)
7. 자바환경에서 보안 구현
언어차원과 컴파일러, 클래스 로더, 바이트코드 검증기(Verifier) 등 계층적으로 위해한 코드를 차단해줍니다.
8. 자바 애플리케이션의 배포방식
.zip 또는 .jar로 압축해서 배포합니다. .jar은 단순히 소스만 압축할 수도 있고, 클래스파일까지 함께 압축해서
실행가능한 형태로 만들 수 있습니다. 웹에서는 .war 형태로 압축해서 배포됩니다.
9. JDK(Java Development Kit)
통상 J2SE를 지칭합니다.컴파일러, 코어클래스 라이브러리, 디버거, JVM, JAR(Java ARchive utility) 등으로
구성됩니다. Java 1.2버전 이후부터 대폭 내부구조가 개선되었는데 이를 표현하기 위해 1.2버전 이후부터는
JAVA2라고 부릅니다. (웹2.0 처럼 큰 변화가 있었다는 의미이지요).
JAVA2에는 J2SE, J2ME, J2EE 이렇게 3가지가 있습니다.
J2ME는 모바일 환경의 S/W 작성을 위해 필요한 클래스만 추려낸 버전이고, J2EE는 기업환겨에 맞게 병렬실행
등을 강화한 버전입니다.
10. 자바빈즈(JavaBeans)
Beans는 땅콩을 의미하는 땅콩은 알맹이를 껍데이가 감싸는 형태로 되어있죠.
클래스가 속성과 메소드를 깜싸고 있는 모습이 흡사 땅콩과 같다해서 자바빈즈라고 부릅니다.
보통 프레임워크에서 데이터 속성과 표준화된 getter, setter를 갖는 클래스를 빈즈라고 합니다.
11. 기본형 데이터 타입
기본형 |
크기 |
Wrapper 클래스 |
비고 |
boolean |
16비트 |
Boolean |
true, false |
char |
8비트 |
Character |
유니코드 사용 |
byte |
8비트 |
Byte |
|
short |
16비트 |
Short |
|
int |
32비트 |
Integer |
|
long |
64비트 |
Long |
|
float |
32비트 |
Float |
|
double |
64비트 |
Double |
|
'언어로그 > Java' 카테고리의 다른 글
| [java] 글 목록 (0) | 2015.09.03 |
|---|---|
| [Java] 자바란? (0) | 2013.02.16 |
| [java] 라이프 게임 (life game) (1) | 2013.02.03 |
| [java] 제13회 한국자바개발자 컨퍼런스 (0) | 2013.01.30 |
| Inner Class(내부 클래스) (0) | 2011.04.12 |
| 컬렉션(Collection) (0) | 2011.04.11 |
설정
트랙백
댓글
글
[java] 라이프 게임 (life game)
스프링노트를 운영하던 시절 썼던 글인데 티스토리로 옮기면서 다시 읽어 보니 감회가 새롭네요
요즘엔 AWT/Swing 이 거의 쓰이지 않지만 이때 공부했던 GUI 프로그래밍이 이후에 플렉스와 아이폰을
공부하면서 GUI에 적응하는데 밑거름이 되었던 것 같네요!
1. 라이프 게임 개발을 시작하다
2008년 6월 25일 수요일 새벽 잠들기 전....
1년간 프로그래밍에 전혀 손 대지 않다가... 다시 프로그래밍을 하려고 하니 영~ 힘들다
1년이란 시간이 매우 길긴 기나부다...그 많은 것을 잊어버렸다. 자바 Spring 프레임워크를 파보려고 하는데
읽어도 무슨말인지 모르겠고, 이클립스 등 개발환경 셋팅하는데만 하루가 걸렸다. ㅡㅡ;;
잊어버린 자바 관련 지식을 상기시키고자, 첫 번째 프로젝트에 들어갔다. 프로그램은 "콘웨이"에 '라이프 게임!'
게임 알고리즘이 간단해서 연습용 프로젝트에 딱인 것 같다.
그럼 라이프 게임이 무엇인지부터 알아보자!
2. 라이프 게임이란?
라이프 게임(Game of Life) 또는 생명 게임은 영국의 수학자 존 호튼 콘웨이가 고안해낸 세포 자동자의
일종으로, 가장 널리 알려진 세포 자동자 가운데 하나이다. 미국의 과학잡지 사이언티픽 어메리칸 1970년
10월호 중 마틴 가드너의 칼럼 〈Mathematical Games(수학 게임)란을 통해 처음으로 대중들에게 소개되어
단순한 규칙 몇가지로 복잡한 패턴을 만들어낼 수 있다는 점 때문에 많은 관심과 반응을 불러일으켰다.
설명
이 ‘게임’은 사실 게임을 하는 사람이 자신의 의지로 게임의 진행을 결정하는 일반적인 게임과는 다르다.
라이프 게임의 진행은 처음 입력된 초기값만으로 완전히 결정된다.
라이프 게임은 무한히 많은 사각형(혹은 ‘세포’)로 이루어진 격자 위에서 돌아간다. 각각의 세포 주위에는
인접해 있는 여덟 개의 ‘이웃 세포’가 있으며, 또 각 세포는 ‘죽어’ 있거나 ‘살아’ 있는 두가지 상태중
한가지 상태를 갖는다. 격자를 이루는 세포의 상태는 연속적이 아니라 이산적으로 변화한다. 즉, 현재 세대의
세포들 전체의 상태가 다음 세대의 세포 전체의 상태를 결정한다.
...
패턴의 예
라이프 게임에는 전혀 변화가 없는 고정된 패턴(정물 靜物, still life), 일정한 행동을 주기적으로 반복하는 패턴
(진동자, oscillator), 한쪽 방향으로 계속 전진하는 패턴(우주선, spaceship) 등 여러 패턴이 존재한다.
‘block’과 ‘boat’는 정물이고, ‘blinker’와 ‘toad’는 진동자, 그리고 ‘글라이더(glider)’와 ‘경량급 우주선(lightweight spaceship — LWSS)’은 우주선에 속한다...
출처 Wikipedia
3. 게임 규칙
게임규칙을 요약하면 아래와 같다
* 셀의 상,하,좌,우,각 대각선 8개의 인접한 셀을 이웃으로 한다.
* 셀은 세대를 거듭하며 살거나 죽는다.
1. 정확히 3개의 이웃이 살아있다면, (죽어있는) 셀이 살아난다.
2. 2개의 이웃이 살아있다면 살아있는 셀은 다음세대에도 살아남든다
3. 1개 이하 또는 4개 이상의 이웃이 살아있다면, 살아있는 셀은 외로워서 또는 질식해서 죽는다.
4. 구현하기
프로그래밍을 하기 위하여 구현한 절차는 아래와 같다.
먼저 모든 셀들을 순회하면서 살아있는 이웃셀을 카운트하고, 살아있는 이웃의 개수를 저장한다
이를 바탕으로 위 세가지 규칙을 적용하여 다음세대 살아있는 셀들을 결정한다.
간략하게 만들어 화면은 아래와 같다.
4.1 게임판의 표현
게임판은 JPanel을 상속하는 Cell을 가로, 세로 size 개수 만큼의 요소로 갖는 이차원 배열로 표현하였다.
LifeGame 클래스는 게임의 전체적인 흐름을 관리하는 메소드들을 갖는다.
public class LifeGame extends JPanel {
...
private void init() {
setLayout(new GridLayout(size,size));
cells = new Cell[size][size];
for (int i=0; i < size; i++)
for (int j=0; j < size; j++) {
cells[i][j] = new Cell();
cells[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
add(cells[i][j]);
}
rule = new GameRule(cells);
}
...
public void transition() {
rule.countAliveNeibor();
rule.applyRule();
}
...
}
4.2 셀의 표현과 셀의 상태
Cell은 live 상태(true이면 살아있고, false 죽어있는 상태)와 살아있는 이웃의 개수에 대한 변수를 갖는다.
live 상태에서 따라서 셀이 그려지거나 혹은 그려지지 않거나 한다.
public class Cell extends JPanel {
private boolean live = false;
private int neighborCount = 0;
private Image img = null;
private int w, h;
...
@Override
protected void paintComponent(Graphics g) {
...
if (live) {
gg.drawImage(img, 0, 0, this);
}
else {
gg.setColor(getBackground());
gg.fillRect(0, 0, getWidth(), getHeight());
}
g.drawImage(image, 0, 0, this);
}
}
4.3 게임규칙의 표현
턴마다 LifeGame 클래스의 transition()메소드가 호출되면, GameRule 클래스의 countAliveNeibor() 메소드가
먼저 호출되고, 이웃하는 셀들에 개수를 모두 카운팅 한뒤, 살아있는 세대를 결정하기 위해 applyRule()메소드가 호출된다.
public class GameRule {
...
public void countAliveNeibor() {
...
}
public void applyRule() {
int neighborCount;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
neighborCount = cells[r][c].getNeighborCount();
if (cells[r][c].getLife()) {
if (neighborCount <= 1 || neighborCount >= 4)
cells[r][c].setLife(false);
}
else {
if (neighborCount == 3)
cells[r][c].setLife(true);
}
}
} //for
}
}
5. 버려진 프로그램은 싫다! 리팩토링~
2009년 08월 04일
예전에 만든 라이프게임 UI가 허접해서 라이프게임 알고리즘은 그대로 드고, 드로잉부분만 수정해서 다시 만들어봤다.
기존에는 메인패널 하나에 좌표를 가지고 Graphics 객체의 드로잉 메소드로 그렸지만, 이번에는
셀하나가 JPanel을 상속하게 했고, 셀이 살아있으면, 이미지를 로딩해서 그리게 했다.
빠른 드로잉을 위해 역시 더블 버퍼링을 사용한다
Timer로는 javax.util.Timer를 사용했다.
TimerTask 쓰레드를 정의해서, 2초마다 상태전이(transition) 후 드로잉하도록 했다.
pauser 기능은 wait() / notify() 를 사용해서, TimerTask 쓰레드를 wait()로 대기상태로 만들고
notifyAll()로 다시 깨우도록 처리했다.
6. 개발하게 하면서 이런걸 알게되었다~
1. AWT의 컴포넌트(Canvas)와 Swing의 컴포넌트(JMenu)를 함께 사용하면, Canvas에 가려 메뉴가 안보인다
중량컨테이너(High Weight Container)인 AWT 와 경량컨테이너(Light Weight Container)인 Swing을 함께
사용해서 그렇다고 한다. 따라서 중량 컨테이너와 중량 컨테이너를 함께 사용하지 말아야 한다.
Swing에서는 Canvas대신 Panel을 사용한다
2. Javax.swing.Timer 객체를 통해 타이머를 구현할 수 있다.
Javax.swing.Timer timer = new Timer(int timeoutMil, ActionListener listener);
3 . 더블버퍼링
Image buffer = Component.createImage(int width, int height); 컴포넌트에 버퍼를 얻고,
Graphics g = buffer.getGraphics(); 그래픽스 객체 g에 드로잉한다
Componet.getGraphics().drawImage(buffer, posintX, positionY, Componet); 버퍼를 컴포넌트에 덮는다
4. 이차원 배열의 사용
Cell을 표현하는 이차원 배열의 생성은 다음과 같다
Cell[][] cell = new Cell[size][size];
for (int i=0; i < size; i++)
for (int j=0; j < size; j++)
cell[i][j] = new Cell();
주의할 점은 Cell 타입의 이차원배열을 생성하고, 그 이차원 배열을 순회하며 실제로 각 배열의 원소에 Cell 객체를
생성하고 할당해야 한다는 것!
7. 만들면서 삽질하게 만든 요인들
첫째로,
타이머 이벤트 발생할 때마다, JPanel 클래스를 상속한 MyPanel에서 public void paint(Graphics g)
메소드를 오버라이드 했는데, 해당좌표에 셀이 도무지 제대로 그려지지 않았다 --^;
갖은 실수 끝에 실수로 알고리즘 메소드가 주석처리 되었었다는 사실을 깨닫고 수정했다. otz...
둘째로,
이전 라이프셀이 지워지지 않는채, 계속 덮입혀져 그려진다. 이것은 더블버퍼링을 이용해서 해결!
생각보다 자바의 드로잉은 속도가 느려서 더블버퍼링을 사용하지 않으면, 화면갱신이 드로잉을 따라가지
못하는 것 같다.
셋째로,
AWT에서의 Canvas 대신, Swing에서는 JPanel을 사용하는데, 드로잉을 하는데 있어서 잘 생각해야 한다.
프로그램이 시작되자 마자 JPanel에 무엇이 그려져야 한다면, 더더욱 그렇다. 게임이 시작하자마자 셀라인을
보이게 하려고 했다. JFrame의 생성자에 그리는 코드를 넣을게 아니라, public void paint(Graphics g) 메소드에서
처리하면 해결할 수 있다. 이때 그리는데 필요한 데이터값이 정확히 대입이 됐는지 잘 살펴야, 삽질을 피할수 있다.
어쨌든 이래저래 해서, 몸풀기 자바 프로그램을 완성했다. 요거 하면서 그나마 잊어버렸던 자바 지식들을 조금씩
기억하게 되어 도움이 되었다.
8. 짜잔~ 최종적으로 만들어진 프로그램
소스 다운로드
다음은 LifeGame, GameRule, Cell 클래스 소스이다.
package lifegame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class LifeGame extends JPanel {
private Cell[][] cells;
private int size;
private GameRule rule;
public LifeGame(int size) {
this.size = size;
init();
}
// 초기화
private void init() {
setLayout(new GridLayout(size,size));
cells = new Cell[size][size];
for (int i=0; i < size; i++)
for (int j=0; j < size; j++) {
cells[i][j] = new Cell();
cells[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
add(cells[i][j]);
}
rule = new GameRule(cells);
}
public void cellAlive(int r, int c) {
cells[r][c].setLife(true);
}
public void cellDead(int r, int c) {
cells[r][c].setLife(false);
}
public boolean getLifeCell(int r, int c) {
return cells[r][c].getLife();
}
public void clearGame() {
for (Cell[] cs : cells)
for (Cell c : cs)
c.setLife(false);
}
public void transition() {
rule.countAliveNeibor();
rule.applyRule();
}
@Override
protected void paintComponent(Graphics g) {
for (Cell[] cs : cells)
for (Cell c : cs)
c.repaint();
}
}
package lifegame;
public class GameRule {
private Cell[][] cells;
private static final int LEFT = -1, UP = -1;
private static final int RIGHT = 1, DOWN = 1;
private int rows, cols;
public GameRule(Cell[][] cells) {
this.cells = cells;
rows = cells.length;
cols = cells[0].length;
}
// 각 셀의 살아있는 이웃을 센다
public void countAliveNeibor() {
int nNeighbor;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
nNeighbor = 0;
if (r + UP >= 0)
if(cells[r + UP][c].getLife())
nNeighbor++;
if (r + UP >= 0 && c + RIGHT < cols)
if (cells[r + UP][c + RIGHT].getLife())
nNeighbor++;
if (c + RIGHT < cols)
if (cells[r][c + RIGHT].getLife())
nNeighbor++;
if (r + DOWN < rows && c + RIGHT < cols)
if (cells[r + DOWN][c + RIGHT].getLife())
nNeighbor++;
if (r + DOWN < rows)
if (cells[r + DOWN][c].getLife())
nNeighbor++;
if (r + DOWN < rows && c + LEFT >= 0)
if (cells[r + DOWN][c + LEFT].getLife())
nNeighbor++;
if (c + LEFT >= 0)
if (cells[r][c + LEFT].getLife())
nNeighbor++;
if (r + UP >= 0 && c + LEFT >= 0)
if (cells[r + UP][c + LEFT].getLife())
nNeighbor++;
cells[r][c].setNeighborCount(nNeighbor);
}
} // for
}
// 살아있는 셀은 이웃이 1명 이하, 4명 이상이면 죽는다
// 죽어있는 셀은 이웃이 3명이면 살아난다
// 이웃이 2,3명인 살아있는 셀은 계속 산다
public void applyRule() {
int neighborCount;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
neighborCount = cells[r][c].getNeighborCount();
if (cells[r][c].getLife()) {
if (neighborCount <= 1 || neighborCount >= 4)
cells[r][c].setLife(false);
}
else {
if (neighborCount == 3)
cells[r][c].setLife(true);
}
}
} //for
}
}
package lifegame;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.io.BufferedInputStream;
import javax.swing.JPanel;
import javax.imageio.ImageIO;
@SuppressWarnings("serial")
public class Cell extends JPanel {
private boolean live = false;
private int neighborCount = 0;
private Image img = null;
private int w, h;
public Cell() {
try {
img = ImageIO.read(new BufferedInputStream(Res.class.getResourceAsStream("../life.png")));
w = img.getWidth(this);
h = img.getHeight(this);
setPreferredSize(new Dimension(w,h));
} catch (Exception e) {
e.printStackTrace();
}
}
public void setLife(boolean s) {
live = s;
}
public boolean getLife() {
return live;
}
public void setNeighborCount(int n) {
neighborCount = n;
}
public int getNeighborCount() {
return neighborCount;
}
@Override
protected void paintComponent(Graphics g) {
// 더블 버퍼링
Image image = createImage(getWidth(), getHeight());
Graphics gg = image.getGraphics();
if (live) {
gg.drawImage(img, 0, 0, this);
}
else {
gg.setColor(getBackground());
gg.fillRect(0, 0, getWidth(), getHeight());
}
g.drawImage(image, 0, 0, this);
}
}
'언어로그 > Java' 카테고리의 다른 글
| [java] 글 목록 (0) | 2015.09.03 |
|---|---|
| [Java] 자바란? (0) | 2013.02.16 |
| [java] 라이프 게임 (life game) (1) | 2013.02.03 |
| [java] 제13회 한국자바개발자 컨퍼런스 (0) | 2013.01.30 |
| Inner Class(내부 클래스) (0) | 2011.04.12 |
| 컬렉션(Collection) (0) | 2011.04.11 |
설정
트랙백
댓글
글
[java] 제13회 한국자바개발자 컨퍼런스
올해도 어김없이 코엑스 그랜드볼룸에서 열리는 한국개발자 컨퍼런스 !
2011년 난생 처음 JCO를 방문하고 두근거렸던 설렘이 엊그제 같은데
어느덧 2년이라는 시간이 흘렀네요ㅜㅠ
아이폰 개발을 하면서 자바에는 소홀해졌었는데...이번 JCO를 기점으로 다시한번
자바에 대한 열정을 불태워야겠습니다!!
11회 때 축하공연을 한 달샤벳도 굉장히 인상적이었는데, 12회때는 축하공연이 없어서
살짝 아쉬웠다는... ㅎㅎ
유익하고 개발자들의 탐구욕을 자극시켜줄 한국 자바 개발자 컨퍼런스를 기대해 봅니다.
보너스로 ... 11회때 공연마치고 차량으로 복귀하는데 "이쪽 좀 봐주세요!" 하는 외침에
난감한 표정으로 답하는 세리양 이네요 ㅎ
'언어로그 > Java' 카테고리의 다른 글
| [Java] 자바란? (0) | 2013.02.16 |
|---|---|
| [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 |
설정
트랙백
댓글
글
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) 리플렉션(Reflection)
작성할 수 있다. 하지만 리플렉션을 사용하면 좀더 유연한 프로그램을 작성할 수 있다. 자바에서 리플렉션을
이해하기 위해서, 자바 클래스 파일은 바이트 코드로 컴파일 되며 실행시간에 이 바이트 코드가 해석되어
실행된다는 것을 아는 것이 첫 출발점이 된다. 이 바이트 코드에는 클래스에 대한 모든 정보를 포함하고 있다.
클래스 파일이 있는 위치와 이 클래스 파일의 이름을 알수 있다면 언제든지 바이트 코드를 뒤져서 클래스에 대한
정보를 얻어낼 수 있다. 이제부터 리플렉션을 통해 어떻게, 어떤 정보를 얻을 수 있는지 알아보자.
1. 리플렉션(Reflection)
클래스를 사용할 수 있는 기법을 의미한다. 마치 거울에 비친 모습과 유사하여 리플렉션이란 이름을 붙힌 것 같다.
2. 리플렉션을 사용하는 이유
위임 클래스를 리플렉션을 통해 동적/정적으로 생성하고 교체하는 방식으로 사용된다. 프레임워크에서 유연성이 있는 동작을
위해 자주 사용되는 방식이기도 하다.
3. 리플렉션을 통해 얻을 수 있는 정보
ClassName Class Modifiers (public, private, synchronized 등) Package Info Superclass Implemented Interfaces Constructors Methods Fields Annotations
3.1 Class Object
프리미티 타입과 배열 타입을 포함하여 자바의 모든 타입들은 연관된 Class 객체를 가지고 있으며, 컴파일 타임에
클래스의 이름을 알수 있다면, 다음과 같이 Class 객체를 얻을 수 있다.
Class myObjectClass = MyObject.class컴파일 타임에 이름을 알수 없다면, 런타임에 문자열로 된 이름으로 부터 클래스 객체를 아래와 같이 얻을 수 있다.
String className = ... // 클래스 풀네임 Class myObjectClass = Class.forName(className);이때 문자열로 된 클래스 이름은 패키지 경로까지 포함한 풀네임이여야 하며, 해당 패키지에 클래스가 존재하지 않으면
Class.forName 메소드는 ClassNotFoundException 예외를 던지게 된다.
3.1 Class Name
있고, getSimpleName() 을 사용하여 패키지가 포함되지 않은 클래스 이름을 얻을 수 있다.
// 클래스 풀네임 Class aClass = ... // 이전에 얻은 클래스 객체 String className = aClass.getName();
// 클래스 심플 네임 Class aClass = ... // 이전에 얻은 클래스 객체 String simpleClassName = aClass.getSimpleName();
3.2 Modifier
통해 해당 플래그가 켜져있는지 확인할 수 있다.
// 변경자 얻기 Class aClass = ... // 이전에 얻은 클래스 객체 int modifiers = aClass.getModifiers();
// 변경자 플래그 확인 메소드들 Modifier.isAbstract(int modifiers) Modifier.isFinal(int modifiers) Modifier.isInterface(int modifiers) Modifier.isNative(int modifiers) Modifier.isPrivate(int modifiers) Modifier.isProtected(int modifiers) Modifier.isPublic(int modifiers) Modifier.isStatic(int modifiers) Modifier.isStrict(int modifiers) Modifier.isSynchronized(int modifiers) Modifier.isTransient(int modifiers) Modifier.isVolatile(int modifiers)
3.3 Package Info
다음과 같이 Class 객체로부터 패키지에 대한 정보를 얻는다.
// 패키지 정보 얻기 Class aClass = ... // 이전에 얻은 클래스 객체 Package package = aClass.getPackage();
Manifest 파일에서도 이 패키지에 대한 특정한 정보를 얻을 수 있다.
(예를 들면 Manifest 파일에 지정된 패지키 버전 번호 같은...)
3.4 Superclass
아래와 같이 수퍼클래스의 class 객체를 얻을 수 있다.
// 수퍼 클래스의 class 객체 얻기 Class superclass = aClass.getSuperclass();
3.5 Implemented Interfaces
클래스 객체에 의해 구현된 인터페이스의 목록을 얻어보자.
// 구현한 인터페이스 목록 얻기 Class aClass = ... // 이전에 얻은 클래스 객체 Class[] interfaces = aClass.getInterfaces();
해당 인터페이스는 목록에 포함되지 않는 것에 주의하자. 구현하는 완전한 인터페이스의 목록을 얻기 위해서는
자신의 수퍼클래스의 구현 인터페이스 목록을 재귀적으로 확인해야 한다.
3.6 Constructors
다음과 같이 클래스의 생성자 목록에 접근한다.
// 클래스 생성자 목록 얻기 Constructor[] constructors = aClass.getConstructors();
3.7 Methods
다음과 같이 클래스의 메소드들에 접근한다.
// 메소드 목록 얻기 Method[] methods = aClass.getMethods();
3.8 Fields
다음과 같이 클래스의 멤버 변수들에 접근한다.
// 필드 목록 얻기 Field[] fields = aClass.getFields();
3.9 Annotations
다음과 같이 클래스의 어노테이션에 접근한다.
// 어노테이션 목록 얻기 Annotation[] annotations = aClass.getAnnotations();
※ 리플렉션을 사용하여 Annotation을 처리하는 것은 아래 포스트를 참고!!
Java-어노테이션(Annotation)
Java-어노테이션 사용하기
4. 리플렉션 사용 예
Board 클래스에 대한 정의는 아래와 같다.
package com.tistory.hiddenviewer.reflection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class Board implements ActionListener{
public final static String boardName = "MyBoard";
public ArrayList boardList;
public int seq;
protected String title;
private String contents;
public Board() {
this(10);
}
public Board(int count) {
this.boardList = new ArrayList(count);
}
public int getSeq() {
return seq;
}
public void setSeq(int seq) {
this.seq = seq;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContents() {
return contents;
}
public void setContents(String contents) {
this.contents = contents;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Board 클래스에 대한 정보를 리플렉션을 사용하여 출력하였다.
package com.tistory.hiddenviewer.reflection.executor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class BoardReflectionExecutor {
public static void main(String[] args) throws IOException, ClassNotFoundException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("생성할 클래스 이름을 입력하세요(패키지 포함): ");
String className = br.readLine();
Class cls = Class.forName(className);
// 클래스 이름얻기
String classFullName = cls.getName();
String classSimpleName = cls.getSimpleName();
System.out.println("class full name: " + classFullName);
System.out.println("class simple name: " + classSimpleName);
// 변경자 얻기
int modifiers = cls.getModifiers();
if (Modifier.isPublic(modifiers)) {
System.out.println("class is public class");
}
if (Modifier.isFinal(modifiers)) {
System.out.println("class is final class");
}
// 패키지 얻기
Package pkg = cls.getPackage();
System.out.println("package name: " + pkg.getName());
// 수퍼클래스 얻기
Class superCls = cls.getSuperclass();
System.out.println("super class name :" + superCls.getName());
// 구현 인터페이스 목록 얻기
Class[] interfaces = cls.getInterfaces();
for (Class cs : interfaces) {
System.out.println("this class implements " + cs.getName() + " interface");
}
// 생성자 목록 얻기
Constructor[] conturctors = cls.getConstructors();
for (Constructor constructor : conturctors) {
System.out.println("Constructor: " + constructor.getName());
}
// 메서드 목록 얻기
Method[] methods = cls.getMethods();
for (Method method : methods) {
System.out.println(method.getReturnType() + " " + method.getName() + "(...)");
}
// 프로퍼티 목록 얻기
Field[] fields = cls.getFields();
for (Field field : fields) {
System.out.println(field.getType() + " " + field.getName());
}
// 어노테이션 얻기
Annotation[] annotations = cls.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.toString());
}
}
}
출력결과
다음 포스팅에서는 리플렉션을 사용하여 실세로 해당 타입의 객체를 생성 / private 필드에 접근 / 메소드를 호출 하는 방법에
대해 알아보자.
'언어로그 > Java' 카테고리의 다른 글
| 리플렉션으로 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 |
| [Java] 어노테이션(Annotation) (2) | 2011.03.15 |
설정
트랙백
댓글
글
예외처리 (Exception Handling)
언어에서는 함수의 반환값을 통해 에러 유무를 판단하였다. 매번 반환값을 검사하는 작업은 상당히 번거롭고,
그 반환값의 의미 또한 프로그래머가 인지하기 어려운 형태여서 에러처리가 불편하였다. 반면 예외처리 방식은
예외가 발생하면 그에 대한 정보를 얻을 수 있고, 제어 흐름 또한 쉽게 이동시킬 수 있는 방식이다.
하지만 아무리 언어차원에서 좋은 메커니즘을 제공하더라도 언제, 어떻게 사용해야하는지 모른다면 무용지물이다.
C++와 Java 언어를 처음 접했을 때에도 언제, 어디서 예외를 던지고 잡아야 하는지가 난제였다. 예외처리에 대해서
좀더 자세히 알아보자.
시기이다. 하지만 모든 에러를 컴파일 시에 검출할 수 는 없으며, 실제론 실행시점에 어떠한 절차를 거치면서 심각한 문제들이
더 발생하게 된다. 발생한 에러는, 프로그램이 수행하는 절차와 연관되어 그 에러를 올바르게 처리하는 방법을 아는 수신자가
처리해야한다. 그렇다. 처리하는 방법을 아는 수신자가 처리하게 해야하는 것이 정답이다. 이 개념을 설명하기에 앞서
자바에서 지원하는 예외(Exception) 클래스에 대해서 알아보자.
1. 예외란 무엇인가?
예외란 프로그램 절차상에서 정상 흐름을 벗어난 이벤트이다.
2. 자바의 예외처리 장점
그에 대한 예외처리는 catch {} 라는 별도의 블럭에서 수행도히기 때문에 로직과 예외처리 영역이 명확히
분리가 된다. 또한 예외처리 영역에서는 예외클래스의 이름을 바탕으로 예외의 종류, 발생위치와 관련된 정보를
확인할 수 있다. (예외이름이 발생한 문제를 나타내도록 알아보기 쉽게 지어야 하는 이유이다.)
3. 예외관련 클래스 상속도
처리 될 수 있는 문제들을 Exception 이라 하며, 심각한 문제들로 시스템을 중단해야할 문제들을 Error 라고 한다.
일반적으로 Checked Exception을 상속하는 커스텀 예외 클래스를 생성하여 사용한다.
대한 결정은 처리 절차에 의존한다.
- 예외 발생시 어떻게 해야하는지 알고있는 절차를 다루는 클래스에게 까지 예외를 throw 하자.
다음 일반적인 프로그래밍 패턴 중에 언제 throw 와 try~catch 할지에 대한 사항이다.
5.1 checked Exception
컴파일 타임 예외로, 비지니스 데이터에 위해한 예외로 시스템 서비스에 부자연스러움을 가져오는 예외이다.
소스에 예외처리를 하지 않으면, 컴파일러 에러가 발생한다.
런타임 예외로, 비지니스 데이터에 위해하지 않지만, 시스템에 영향을 미칠 수 있는 예외이다.
프로로램 자체상의 에러로, 프로그램 작성을 잘 못했을 때 발생한다.
다음은 checked 예외인 Exception 을 상속하여, 다양한 생성자를 갖도록 오버로딩하여 사용하는 예이다.
'언어로그 > 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 |
JDK_000_LifeGame.zip