- AntiStroy 님의 블러그에서 퍼왔음을 알립니다.

프로젝트를 진행하면서 JNI에 대해 알게 되었었다. Java에서 C함수를 호출하거나 C에서 Java의 메소드를 호출할 때 사용하는 것인데, 안드로이드 공부를 하다가 조금 더 파고들게 되었다. 

* 안드로이드는 자바로 프로그래밍을 하는데 왜 JNI에 대해 알아야 할까?
우선 안드로이드 플랫폼은 순수하게 Java로만 구성되어진 것이 아닌 Java 레이어와 C/C++레이어가 서로 상호 작용하면서 동작한다. 이 두 레이어가 유기적으로 동작하게 만들려면 JNI에 대해 알아야 한다. 
그리고 일반적으로 Java는 C/C++에 비해 느리다. 성능이 중요할 경우 C/C++로 작성하고 이를 JNI를 통해 Java에서 호출할 수 있다.

* NDK(Native Development Kit)
안드로이드 애플리케이션에서 사용할 네이티브 라이브러리를 작성하기 위한 도구 모음.
실제로 모듈을 구현하기 위해서는 JNI에 대한 지식 필요

* JNI의 개발 순서
1. Java 코드 작성
2. Java 코드 컴파일
3. C 헤더 파일 생성
4. C 코드 작성
5. C 공유 라이브러리 생성
6. Java 프로그램 실행

1. Java 코드 작성


public class AtinJNI {
// 네이티브 메소드 선언 
native void printAtin();
native void printString(String str);
  // 라이브러리 로딩
static {System.loadLibrary("atinjni");}
public static void main(String args[]){
AtinJNI myJNI = new AtinJNI();
  // 네이티브 메소드 호출
myJNI.printAtin();
myJNI.printString("Hello Atin");
}
}

[Source 1] AtinJNI.java

[표 1] 플랫폼별 System.loadLibrary() 메소드가 로딩하는 C라이브러리 형식
 호스트 플랫폼  실제 로드되는 C 라이브러리 
 Window   libname.dll 
 Linux   libname.so 


2. Java 코드 컴파일
javac를 통해서 .java파일을 .class로 컴파일한다.
 javac AtinJNI.java

위와 같은 명령을 실행할 경우 아무 에러가 나지 않는다면 .class로 컴파일 된 것이다.

3. C 헤더 파일 생성
이제 Java 소스를 만들었으니 C 소스를 짜야 한다. 그런데 중요한 점은 어떻게 Java에서 호출되는 C 소스를 짤 것인가이다. 이것을 위해 javah라는 툴이 있다. 이 툴을 사용하면 .class파일을 파싱해서 만들어야 할 C 함수의 헤더를 만들어준다. 

javah <native로 선언된 메소드를 포함한 자바 클래스명>
- <JDK_HOME>\bin에 포함.
- Java 네이티브 메소드와 연결될 수 있는 C함수의 원형 생성

 javah AtinJNI
위와 같은 명령어를 실행하면 AtinJNI.h라는 헤더 파일이 생성됀다.

내용은 아래와 같다.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class AtinJNI */

#ifndef _Included_AtinJNI
#define _Included_AtinJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     AtinJNI
 * Method:    printHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_AtinJNI_printHello
  (JNIEnv *, jobject);

/*
 * Class:     AtinJNI
 * Method:    printString
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_AtinJNI_printString
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

[Source 2] AtinJNI.h

4. C 코드 작성
위에서 생성한 AtinJNI.h의 헤더를 기준으로 C 소스를 작성하면 됀다. 


#include "HelloJNI.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_AtinJNI_printAtin
  (JNIEnv *env, jobject obj)
{
printf("Hello Atin \n");
return;
}

JNIEXPORT void JNICALL Java_AtinJNI_printString
  (JNIEnv *env, jobject obj, jstring string)
{
const char *str = (*env)->GetStringUTFChars(env, string, 0);
printf("%s! \n", str);
return;
}

[Source 3] atinjni.c

5. C 공유 라이브러리 생성
중요한건 Window는 dll, Linux는 so파일을 만들어야 한다. 책에서는 C 소스를 작성 후 cl명령을 통해 dll을 만들었다.

cl 명령은 Visual Studio 2008 명령 프롬프트에서 실행해야 하며 VC 2008 Express Editions(http://www.microsoft.com/express/download/)가 설치되어 있어야 한다.

cl -I"<JDK_HOME>\include" -I"<JDK_HOME>\include\win32" -LD atinjni.c -Featinjni.dll
cl : vc++ 컴파일 명령어
-I<dir> : 헤더 파일을 검색할 디렉토리 경로 <dir> 추가
-LD : DLL 생성
-FE<파일명> : 컴파일 결과 파일 이름 지정

나는 VC에서 직접하고 싶어서 [1]과 같이 dll을 만들었다.
그런데 다음과 같은 문제에 직면했다.


Can't load IA 32-bit .dll on a AMD 64-bit platform
그래. 나는 64비트용 윈도우 7 운영체제였다. 32비트 dll이 문제가 되는 것이었다. 구글링해보니 32비트용으로 Java를 다시 까니 실행 명령어에 옵션을 주는 몇 방법들이 있었는데 마음에 들지 않았다. dll을 64비트용으로 하면 될 것 같았다. 그래서 [2]와 같은 방법으로 dll을 64비트용으로 만들어주었고 문제를 해결했다.

6. Java 프로그램 실행
이클립스라면 그냥 실행하면 되고 콘솔에서라면 "java AtinJNI"로 실행하면 결과를 볼 수 있다.

Reference
[1] VC에서 DLL 만드는 방법 (http://sol9501.blog.me/70102942944)
[2] 64비트용 컴파일 (http://blog.naver.com/PostView.nhn?blogId=honnak&logNo=70085595801&viewDate=&currentPage=1&listtype=0
[3] 인사이드 안드로이드(Inside the Android Framework, 위키북스)


객체지향은 4가지의 특성이 있었다.
하나. 상속성
둘. 다양성
셋. 캡슐화
넷. 정보은닉.
자바에서 말이다.

상속성 : 상속은 부모에서 자식으로, 자식에서 자식으로, 강제형변환, 자동형변환 등등...
다양성 : 여러가지 기능을 호출할 수 있다.
캡슐화 : 기능을 하나로 묻는것.
정보은닉 : 보호하고 싶은 멤버변수를 타클래스에서 볼 수 없게 만든다.

이상.
오늘 배운것을 정리해본다.

수스 안드로이드 2기 수강생~~

'객체지향언어 > Java' 카테고리의 다른 글

자바에서 JNI 사용법  (0) 2011.08.26
자바 첫걸음. "Hello World " 찍어 보기 헤헤  (0) 2011.03.31
java로 윤년구하기.  (0) 2010.08.10
쿠키 생성하는 방법  (0) 2010.06.04
자바 클래스 정의 및 사용방법  (0) 2009.08.19
소스를 적는다. 헤헤
컴파일을 하고 아래와 같이 정상적으로 찍히는지 확인한다.
아 역시 기초가 탄탄해야 실력도 쑥쑥이얌~
아자아자 화이팅

'객체지향언어 > Java' 카테고리의 다른 글

자바에서 JNI 사용법  (0) 2011.08.26
객체지향의 특성에 대해서 배웠다.  (0) 2011.04.05
java로 윤년구하기.  (0) 2010.08.10
쿠키 생성하는 방법  (0) 2010.06.04
자바 클래스 정의 및 사용방법  (0) 2009.08.19

간만에 자바를 이용하여 프로그래밍 공부를 하였다. 후배의 부탁으로 jsp와 서블릿으로 자바를 처음 접하고나서 처음으로 제대로 공부해 보기 위해 책도 구입해서 열공하면서 오늘 코딩한 내용을 붙여넣기 해 본다.
내가 생각해도 오늘은 너무 무리하게 진도를 나간것 같다. 확실히 C언어를 먼저 선행학습해서 그런지 함수사용방법이나 함수선언, 문법 등은 기본가락이 있어서 그냥 넘어갔다. 또한 C++, C#, VB.NET으로 여러 프로젝트를 진행했던지라 그닥 객체지향 쪽도 어렵지 않게 수행할 수 있었다. 오늘 사실 책 전체를 다 봤다. 낼은 시간이 남으면 JFrame 쪽을 공부해야 겠다. 사실 JFrame을 해야 진짜 윈도우프로그램 다운걸 만들지 이런 콘솔은 통신외에는 써먹을때도 없다. 기본로직은 모든 언어와 마찬가지로 비슷하기 때문에 문법만 조금 틀어지기 때문이다. 사실 통신도 C언어나 C++ 만들어서 사용을 마니 하기 때문에 통신부분도 그닥 마음에 들진 않지만 그래도 자바를 공부하고 준비된 모습으로 어디를 가든 자신이 붙을려면 해야 한다고 생각해서 이렇게 작성하고 또 만들어 봐야 겠다. 여러가지 예외사항이나 변수들이 많을꺼라 생각하지만 책에 있는것을 치는것인데 설마 어려울까...

public class IfLeapYear {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  for(int year=1998;year<2006;year++){
   boolean yearTF = false;
   if((0==(year%4)&&0!=(year%100))||0==year%400){
    yearTF = true;
   }else{
    yearTF = false;
   }
   
   if(yearTF){
    System.out.println(year+"는 윤년입니다.");
   }else{
    System.out.println(year+"는 윤년이 아닙니다.");
   }
  }//for

 }

}

import javax.swing.*;
import java.awt.*;
public class Hello4Applet extends JApplet{
 private static final long serialVersionUID=122454214237L;
 public void init(){
  
 }
 public void start(){
  
 }
 public void paint(Graphics g){
  super.paint(g); // 습관적으로 쓰자
  g.drawString("안녕하세요", 50, 50);
 }
}


public class FiveOperation {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  int ia=20;
  int ib=67;
  
  double da=69.67;
  double db=34;
  int iResultA=ia+ib;
  int iResultB=ia-ib;
  int iResultC=ia*ib;
  int iResultD=ia/ib;
  int iResultE=ia%ib;
  
  System.out.println("1:"+iResultA);
  System.out.println("2:"+iResultB);
  System.out.println("3:"+iResultC);
  System.out.println("4:"+iResultD);
  System.out.println("5:"+iResultE);
  
  double dResultA=da/db;
  double dResultB=da%db;
  double dc=(da-db*((int)(da/db)));
  System.out.println("6:"+dResultA);
  System.out.println("7:"+dResultB);
  System.out.println("8:"+dc);
  
  int even=4%2;
  int odd=5%2;
  System.out.println("9:"+even);
  System.out.println("9:"+odd);
  
 }

}

import java.util.*;
public class PrintTest {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  int a=20;
  long b=30000L;
  float c=34.98F;
  double d=234.234;
  char e='k';
  Calendar today=Calendar.getInstance();
  System.out.println("1:"+a+""+b+""+c+""+d+""+e);
  System.out.printf("2: \\ %% %d %d %f %f %c %n", a,b,c,d,e);
  System.out.printf("today %1$tm %1te, %1$tY %n", today);
 }

}

-------------makeCookie.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<html>
<head>
<title>쿠키를 생성하는 예제</title>
</head>
<%
 String cookieName = "myCookie";
 Cookie cookie = new Cookie(cookieName, "hongkd");
 cookie.setMaxAge(60*2);
 cookie.setValue("kimkd");
 response.addCookie(cookie);
%>
<body>
<h2>쿠키를 생성하는 예제</h2>
<p>
"<%=cookieName %>" 쿠키가 생성되었습니다.<br>
<input type="button" value="쿠키의 내용확인"
onclick="javascript:window.location='useCookie.jsp'">
</p>
</body>
</html>

-------------useCookie.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<html>
<head>
<title>웹 브라이저에 저장된 쿠키를 가져오는 예제</title>
</head>
<body>
<h2>웹 브라저에 저장된 쿠키를 가져오는 예제</h2>
 <%
  Cookie[] cookies = request.getCookies();
  if(cookies != null){   
   for(int i=0; i<cookies.length;++i){
    if(cookies[i].getName().equals("myCookie")){
 %>
     쿠키의 이름은 : "<%=cookies[i].getName()%>" 이고,
     쿠키의 값은      : "<%=cookies[i].getValue()%>" 입니다.
      
 <%
             }
   }
  }
 %>
</body>
</html>

쿠키를 생성하고 사용하는 방법이다. 진하게 표시된 부분을 유념해야 한다. 저부분이 틀리면 파라미터를 제대로 전달받지 못해서 노가다하기 싶상이다. 처음이라 그런지 나도 10여분정도 저 부분 찾느라 훈줄이 났다. 책에 있는 데로 그대로 쳤는데 역시 책에 오타였다. 정말 찢어버리고 싶다. 그래도 그책으로 꿋꿋히 버티면서 열공중이다.

1) 객체 모델링

객체 : 사물을 뜻함

객체 모델링 : 객체를 클래스라는 프로그램으로 적용하는 것이다.

예) 급여의 속성 - 기본급,세금,초과근무시간

급여의 동작 - 초과근무시간 계산, 세금계산, 급여계산

객체 모델링 - 특징

특징

맴버변수

기본급

basicSalary

초과근무시간

overTime

이름

name

객체 모델링 - 동작

동작

메소드

초과근무시간계산

overTimeAllowanceCompute()

세금계산

taxCompute()

급여계산

salaryCompute()

2) 클래스의 정의

- 클래스 이름 : Salary

public class Salary

{

int basicSalary; // 기본급

String name; // 이름

int overTime; // 초과근무시간

// "초과근무수당 계산"을 메소드로 구현

public int overTimeAllowanceCompute()

{

return overTime*20000;

}

// "세금 계산"을 메소드로 구현

public double txzCompute()

{

return (basicSalary+overTimeAllowanceCompute())*0.1;

}

// "급여 계산"을 메소드루 구현

public int salaryCompute()

{

return (int)(basicSalary+overTimeAllowanceCompute()-taxCompute());

}

}

- 제어자 : 클래스 및 클래스의 멤버를 정의할 때 필요한 것(접근제어자, 키워드)

- 클래스 멤버 : 메소드, 멤버 변수

class modifier(클래스 제어자)

public,abstract, final

constructor modifier(생성자 제어자)

public,protected,private

method modifier(메소드 제어자)

public,protected,private,abstract,static,

final,native,synchronized

member variable modifier

(맴버 변수 제어자)

public,protected,private,final,static,

transient,volatile

- 클래스 제어자

public : 클래스명과 파일명이 같아야 한다.

abstract : 추상 클래스, 상속을 통해 완성 된다.

final : 상속을 할 수 없는 클래스, 상속을 금지 한다.

예외) 조합을 해서 사용할수 있으나, abstract, final은 같이 쓸 수 없다.

- 생성자 : 객체를 생성할 때 반드시 필요한 것, 생성자를 기술하지 않으면 자바 가상머신이 기본 생성자(default constructor)를 생성한다.

- 메소드 제어자

native : java class에서 C/C++ 언어를 구현할 때 쓰임.

synchronized : 멀티 쓰레드를 제어할 때 사용하는 것.

- 멤버 변수 제어자

transient : 저장시 영구기억장치(하드디스크)에 저장되지 않는다.

volatile : 쓰레드 간에 공유하는 데이터로서 일관성을 유지할 때 사용된다.

- 클래스 사용 방법

선언한 클래스를 사용하기 위해서 클래스는 메모리를 할당 받아야 한다.

객체생성 : 클래스의 객체(인스턴스)를 생성해야 한다.

자바 : 클래스의 객체(인스턴스)를 생성할 때 new라는 키워드를 사용해서 생성한다.

Salary s = new Salary()

레퍼런스타입 클래스의 인스턴스, 객체생성 생성되는 객체 타입

레퍼런스 변수

해당 클래스에 생성자가 없으면 자바 가상머신이 디폴트 생성자를 생성한다.

UML 다이어그램 표현

Salary

basicSalary

name

overTime

멤버변수

+inputData

+overTimeAllowancecompute

+taxCompute

+salaryCompute

+outputData

+main

메소드


자바는 기존의 프로그래밍 언어인 C/C++(이하 C라 명명한다.) 계열과 비슷한 문법을 보이면서도 내부적으로 실행될 때는 확연한 차이점을 가지고 있다. C는 기계어로 번역되고 메모리에 적재되어 CPU에서 직접 처리된다. 반면 자바는 바이트코드(Byte code)라는 특수한 코드로 번역되어 가상의 CPU인 JVM(Java Virtual Machine)이 그 실행을 맡고 CPU에 처리를 맡긴다. 따라서 자바는 JVM이라는 가상의 CPU를 가지고 있기 때문에 플랫폼이 독립적이다.

1. 컴퓨터와 관련하여 플랫폼이라는 용어는 응용프로그램이 실행될 수 있는 기초를 이루는 컴퓨터 시스템을 의미한다. PC에서는 두 개의 서로 다른 플랫폼의 예로서 윈도우95와 매킨토시를 들 수 있으며, 대형 서버나 메인프레임에서는 IBM의 System/390을 하나의 플랫폼으로 볼 수 있다.

하나의 플랫폼은 운영체계, 컴퓨터 시스템의 보조 프로그램, 그리고 마이크로프로세서, 논리연산을 수행하고, 컴퓨터 내의 데이터 이동을 관장하는 마이크로칩 등으로 구성된다. 운영체계는 특정 마이크로프로세서의 명령어셋과 함께 동작할 수 있도록 설계되어야 한다. 예를 들면, 마이크로소프트의 윈도우95는 같거나 비슷한 종류의 명령어셋을 공유할 수 있는 인텔의 마이크로프로세서군과 함께 동작할 수 있도록 만들어졌다. 마더보드나 데이터 버스 등과 같이 어떠한 컴퓨터 플랫폼이라도 보통 다르게 적용된 부품들이 있지만, 이러한 부품들은 점차적으로 모듈화되고 표준화되어가고 있다.

역사적으로 대부분의 응용프로그램들은 특정 플랫폼 상에서만 운영되도록 개발되어 왔다. 각 플랫폼은 다른 시스템 서비스들을 위해 다른 응용프로그램 인터페이스를 제공한다. 그러므로 윈도우 플랫폼에서 운영되기 위해 개발된 PC 프로그램을, 매킨토시 플랫폼에서 운영하기 위해서는 프로그램을 처음부터 다시 개발해야만 했다. 비록 이러한 플랫폼의 차이들은 계속 존재하고, 그들 사이에는 항상 독점기술에 관한 차이가 존재하겠지만, 표준을 따르는 새로운 개방형 인터페이스를 통해 이제는 일부 프로그램들이 다른 플랫폼에서 운영될 수 있고, 브로커 프로그램 등의 중재를 통해 서로 다른 플랫폼 간의 상호 운영이 가능해지고 있다.

2. 플랫폼은 다른 기술들 또는 공정들이 그 위에서 구현될 수 있는 일종의 기술 기반을 의미하기도 한다

내용을 간단히 요약해보면..

cpu가 멀티코어 시대가 되었으며 때문에 2개의 cpu에서 동시에 실행하는 멀티스레드 환경이 되었다. 기존의 Lock 동기화 메커니즘을 사용하면 멀티코어 성능을 제대로 활용할 수 없다. 멀티 스레드에 완벽하게 안전한 언어가 요구된다. 함수 언어는 동기화 없이 멀티스레드에 항상 안전하다. 이렇게 서론을 띄우고 SCALA라는 언어를 소개한다.

SCALA

Scala는 다음 같은 몇 가지 강력한 장점을 가진 함수-객체 혼성 언어다. 다음은 SCALA의 특징이다.

1. 자바 바이트코드로 컴파일되고 JVM 위에서 실행된다. 자바의 풍부한 오픈소스 환경을 활용할 수 있을 뿐 아니라 별도의 이행 비용 없이 현재의 IT 환경에 통합할 수 있다.

2. 스칼라는 하스켈(Haskell)과 ML의 함수 원리에 기반을 두고 있으면서도 여전히 자바 프로그래머가 좋아하는 친숙한 객체 지향 개념을 많이 빌어왔다. 결과적으로 양쪽의 최선을 하나로 녹여냈다.

3. 마지막으로 스칼라는 자바 커뮤니티에서 Pizza와 GJ 언어로 잘 알려진 Martine Odersky에 의해 개발되었다. 참고로 GJ는 현재 Java 5 제네릭스(Generics)의 프로토타입이다. 이 같이 스칼라는 "뭔가 진지한 성과"라는 느낌을 준다. 별 생각 없이 만들어 별 생각 없이 버려지는 언어가 되지는 않을 것이다.

정리해 보자면.. 멀티스레드에 안전하다는 함수적 개념을 도입한 Java의 확정버젼?? 이렇게 해석된다. 믿을만한 사람이 개발했기 때문에 앞으로도 더 발전할 것이라는..

너무 객체지향개념에 얽매여서 고민하기 보다는 일단 프로그램을 기능적으로 완성한 다음 어떻게 하면 보다 객체지향적으로 코드를 개선할 수 있을지를 고민하여 점차 개선해 나가는 것이 좋다.

이러한 경험들이 축적되어야 프로그램을 객체지향적으로 설계할 수 있는 능력이 길러지는 것이지 처음부터 이론을 많이 안다고 해서 좋은 설계를 할 수 있는 것은 아니다.

int iv; // 인스턴스 변수

static int cv; // 클래스 변수

1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통적으로 사용해야하는 것에 static을 붙인다.

2. 클래스변수(static변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.

3. 클래스메서드(static메서드)는 인스턴스변수를 사용할 수 없다.

4. 메서드 내에서 인스턴스변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.

- 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴보고 있으면, static을 붙인다.

- 작성한 메서드 중에서 인스턴스 변수를 사용하지 않는 메서드에 대해서 static을 붙일 것을 고려한다.

class MyMath2{

long a, b;

// 인스턴스변수 a, b만을 이용해서 작업하므로 매개변수가 필요없다.

long add() { return a + b; } // a, b는 인스턴스 변수

// 인스턴스변수와 관계없이 매개변수로만으로 작업이 가능하다.

static long add(long a, long b) { return a + b; } // a, b는 지역변수

}

class MyMathTest2{

public static void main(String args[]){

//클래스메서드 호출

System.out.println(MyMath2.add(200L, 200L));

MyMath2 mm = new MyMath2();

mm.a = 200L;

mm.b = 100L;

System.out.println(mm.add());

}

}

------------------------------------------------------

MemberCall c = new MemberCall();

int result = c.instanceMethod1();

int result = new MemberCall().instanceMethod1();

------------------------------------------------------

기본형 매개변수

------------------------------------------------------

static void change (int x){ // 기본형 매개변수

x =10000;

System.out.println("change() : x = " + x);

}

------------------------------------------------------

참조형 매개변수

------------------------------------------------------

class Data { int x; };

class ParameterTest2 {

public static void main (String[] args) {

Data d = new Data();

d.x = 10;

System.out.println("main() : x = " + d.x);

Change(d);

System.out.println("After Change(d)");

System.out.println("main() : x = " + d.x);

}

static void change (Data d){ // 참조형 매개변수

d.x = 1000;

System.out.println("change() : x = " + d.x);

}

}

------------------------------------------------------

참조형 매개변수

------------------------------------------------------

class ParameterTest3 {

public static void main (String[] args) {

int[] x = {10}; // 크리가 1인 배열. x[0] = 10;

System.out.println("main() : x = " + x[0]);

Change(x);

System.out.println("After Change(x)");

System.out.println("main() : x = " + x[0]);

}

static void change (int[] x){ // 참조형 매개변수

x[0] = 1000;

System.out.println("change() : x = " + x[0]);

}

}

메서드 오버로딩 이란?

한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 메서드 오버로딩(method overloading)또는 간단히 오버로딩(overloading)이라 한다.

오버로딩의 조건

1. 메서드 이름이 같아야 한다.

2. 매개변수의 개수 또는 타입이 달라야 한다.

3. 매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.

(리턴타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.)

오버로딩의 장점

1. 메서드도 변수처럼 단지 이름만으로 구별된다면, 한 클래스내의 모든 메서드들은 이름이 달라야 한다. 근본적으로는 같은 기능을 하는 메서드들이지만, 서로 다른 이름을 가져야 하기 때문에 메서드를 작성하는 쪽에서는 이름을 짓기도 어렵고, 메서드를 사용하는 쪽에서는 이름을 일일이 구분해서 기억해야 하기 때문에 서로 부담이 된다.

2. 메서드의 이름을 절약할 수 있다는 것이다. 하나의 이름으로 여러 개의 메서드를 정의할 수 있으니, 메서드의 이름을 짓는데 고민을 덜 수 있는 동시에 사용되었어야 할 메서드 이름을 다른 메서드의 이름으로 사용할 수 있기 때문이다.

예)

void println()

void printlnBoolean(boolean x)

void printlnChar(char x)

void printlnDouble(double x)

void printlnString(String x)

생성자란?

생성자는 인스턴스가 생성될 때 호출되는 ‘인스턴스 초기화 메서드’이다. 따라서 인스턴스 변수의 초기화 작업에 주로 사용되며, 인스턴스 생성 시에 실행되어야 할 작업을 위해서도 사용된다.

인스턴스 초기화 : 인스턴스변수들을 초기화하는 것을 뜻한다.

생성자 조건

1. 생성자의 이름은 클래스의 이름과 같아야 한다.

2. 생성자는 리턴 값이 없다.

Card c = new Card();

1. 연산자 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.

2. 생성자 Card()가 호출되어 수행된다.

3. 연산자 new의 결과로, 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장된다.

생성자에서 다른 생성자 호출하기 - this(), this

- 생성자의 이름으로 클래스이름 대신 this를 사용한다

- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.

this - 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.

this(), this(매개변수) - 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.

인스턴스를 생성할 때는 다음의 2가지 사항을 결정해야 한다.

1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?

2. 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?

int door = 4; // 기본형(primitive type) 변수의 초기화

Engine e = new Engine(); // 참조형(reference type) 변수의 초기화

오버로딩 vs 오버라이딩

오버로딩 : 기존에 없는 새로운 메서드를 정의하는 것(new)

오버라이딩 : 상속받은 메서드의 내용을 변경하는 것(change, modify)

class Parent {

void parentMethod() {}

}

class Child extends Parent {

void parentMethod() {} // 오버라이딩

void parentMethod(int i) {} // 오버로딩

void childMethod() {}

void childMethod(int i) {} // 오버로딩

void childMethod() {} // 에러, 중복정의 되었음

}

패키지 : 클래스의 묶음

간단한 프로그램이나 애플릿은 패키지를 지정하지 않아도 별 문제 없지만, 큰 프로젝트나 Java API와 같은 클래스 라이브러리를 작성하는 경우에는 미리 패키지를 구성하여 적용하도록 한다.

하나의 소스파일에 단 한번만 선언될 수 있다.

import문

컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공하는 것이다. 컴파일 시에 컴파일러는 import문을 통해 소프파일에 사용된 클래스들의 패키지를 알아 낸 다음, 모든 클래스이름 앞에 패키지명을 붙여 준다.

import문의 선언

모든 소스파일(.java)에서 import문은 package문 다음에, 그리고 클래스 선언 문 이전에 위치해야한다. 그리고 import문은 package문과는 달리 한 소스파일에 여러 번 선언할 수 있다.

1. package문

2. import문

3. 클래스 선언

import 패키지명.클래스명;

import 패키지명.*;

프로그램 오류

프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우가 있다. 이러한 결과를 초래하는 원인을 프로그램 에러 또는 오류라고 한다.

이를 발생시점에 따라 ‘컴파일 에러(compile-time error)’와 '런타임 에러(runtime error)'로 나눌 수 있는데, 글자 그대로 ‘컴파일 에러’는 컴파일 할 때 발생하는 에러이고 프로그램 실행도중에 발생하는 에러를 ‘런타임 에러’라고 한다.

자바에서는 실행 시(runtime) 발생할 수 있는 프로그램 오류를 ‘에러(error)’와 ‘예외(exception)' 두 가지로 구분하였다. 에러는 메모리 부족(outofmemoryerror)이나 스택오버플로우(stackoverflowerror)와 같이 일단 발생하면 복구할 수 없는 심각한 오류이고, 예외는 발생하더라도 수습될 수 있는 비교적 덜 심각한 것이다.

예외처리

정의 - 프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것

목적 - 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지하는 것

class ExceptionEx3 {

public static void main(String arg[]){

int number = 100;

int result = 0;

for (int i=0; i<10; i++){

try{

result = number / (int)(Math.random() * 10);

System.out.println(result);

} catch (ArithmeticException e) {

System.out.println("0");

} // try-catch의 끝

} // for문 끝

}

}

class NewExceptionTest {

public static void main(String arg[]){

try{

startInstall(); // 프로그램 설치에 필요한 준비를 한다.

copyFiles(); // 파일을 복사한다.

} catch (SpaceException e) {

System.out.println("에러 메시지 : " + e.getMessage());

e.printStackTrace();

System.out.println("공간을 확보한 후에 다시 설치하시기 바랍니다.");

} catch (MemoryException me) {

System.out.println("에러 메시지 : " + e.getMessage());

me.printStackTrace();

System.gc(); // Garbage Collection을 수행하여 메모리를 늘려준다.

System.out.println("다시 설치를 시도하세요");

} finally {

deleteTempFiles(); // 프로그램 설치에 사용된 임시파일을 삭제한다.

} // try의 끝

} // main의 끝

static void startInstall() throws SpaceException, MemoryException {

if(!enoughSpace()) // 충분한 설치 공간이 없으면...

throw new SpaceException("설치할 공간이 부족합니다.");

if (enoughMemory()) // 충분한 메모리가 없으면...

throw new MemoryException("메모리가 부족합니다.");

} // StartInstall 메서드의 끝

static void copyFile() {}

static void deleteTempFile() {}

static boolean enoughSapce() {

// 설치하는데 필요한 공간이 있는 확인하는 코드를 적는다.

return false;

}

static boolean enoughMemory() {

// 설치하는데 필요한 메모리공간이 있는 확인하는 코드를 적는다.

return true;

}

} // NewExceptionTest 클래스의 끝

class SpaceException extends Exception {

MemoryException(String msg){

super(msg);

}

}

1. 컬렉션 프레임윅(collection Framework)

- 다수의 데이터를 쉽게 처리할 수 있는 표준화된 방법을 제공하는 클래스들

2. 유용한 클래스 - 알아두면 좋은 아주 쓰이는 클래스들

3. 형식화 클래스 - 데이터를 표준화된 형식으로 출력하는데 도움을 주는 클래스들


그룹이름:Java

 

메뉴제목:Java 컴파일

명령:C:\Program Files\Java\jdk1.5.0_07\bin\javac.exe

인수:공백-d공백.공백$(FileName)

디렉토리:$(FileDir)

 

메뉴제목:Java 실행

명령:C:\Program Files\Java\jdk1.5.0_07\bin\java.exe

인수:$(FileNameNoExt) $(Prompt)

디렉토리:$(FileDir)

 

메뉴제목:RMI 컴파일

명령:C:\Program Files\Java\jdk1.5.0_07\bin\rmic.exe

인수:$(FileNameNoExt)

디렉토리:$(FileDir)

 

메뉴제목:Applet 뷰어

명령:C:\Program Files\Java\jdk1.5.0_07\bin\appletviewer.exe

인수:$(FileName)

디렉토리:$(FileDir)

 

메뉴제목:RMI 레지스트리 실행

명령:C:\Program Files\Java\jdk1.5.0_07\bin\rmiregistry.exe

인수:아무것도 필요없음.^^*

디렉토리:$(FileDir)


 

'객체지향언어 > Java' 카테고리의 다른 글

자바 첫걸음. "Hello World " 찍어 보기 헤헤  (0) 2011.03.31
java로 윤년구하기.  (0) 2010.08.10
쿠키 생성하는 방법  (0) 2010.06.04
자바 클래스 정의 및 사용방법  (0) 2009.08.19
플랫폼 언어 자바  (0) 2009.08.19

+ Recent posts