Effective Java (1)

1. 개요

1.1 목적
언어는 '배우는 것' 이라기 보다는 '성장하는 것' 이다. 이미 Java 언어에 대한 기본 지식을 갖고 있겠지만 본 문서를 통해 많은 것들을 다시 생각해 볼 수 있을 것이다.
본 문서의 원칙 대부분은 다음과 같은 몇 가지 기본 원리에서 출발한다.

1)    명확함(clarity)과 단순함(simplicity)은 가장 중요한 것이다.
2)    모듈은 사용자에게 예측 가능한 행동만 제공해야 한다. 가급적 모듈 사이의 의존성을 줄일 수 있을 만큼 줄여야 한다.
3)    이미 있는 코드를 재사용할 때, 복사하여 붙이는 것이 아니라 있는 그대로 다시 써야한다.
4)    오류는 빨리 발견하는 것이 좋다. 가장 좋은 것은 컴파일 시점에 발견하는 것이다.


1.2 범위
본 문서는 Sun의 ‘The Java Language Specification, Second Edition’ 을 토대로 작성하였으며, 명확하고, 정확하고, 쓰기 편리하고, 강력하고, 유연하고, 유지보수가 쉬운 프로그램을 만들기 위한 전 범위 내에서 활용할 수 있다.

2, Java 기본 요약

2.1.객체지향(object-oriented programming) 프로그래밍
객체 지향이란 시스템을 구성하는 실체로서 각 객체는 한 구성의 특성과 상태변화를 구현 하는 기본 단위라 할 수 있다.
객체는 소프트웨어를 구성하고 실제 소프트웨어를 작동시키는 실체들 즉, 논리와 데이터가 분리되어 있는 기존의 구조적 사고에서 탈피하여 논리와 데이터가 결합된 객체들이 시스템을 이룬 것이다. (자료구조와 행위가 결합된 구조화된 집합)
 
 - 생산성 향상 : 잘 설계된 클래스들 즉 라이브러리를 재사용함으로써 생산성을 증대.
 - 자연적인 모델링 :
   객체, 클래스, 속성, 상속 및 다형성 등은 우리의 일상생활에서 보통 사람들이 대하고 생각하는 방식을 그대로 프로그램 언어로
   표현 할 수 있게 해준다.
 - 재사용성(Reuse) : 기존 프로그램이 갖고 있는 특성들을 상속 받아 재정의 및 사용.
 - 유지보수(maintenance) :
   기존 기능을 수정 시 함수를 새롭게 바꾸더라도 캡슐화(데이터와 이를 조작하는 코드를 결합하여 외부의 간섭과 오용으로부터
   코드와 데이터를 안전하게 유지)와 그 함수의 세부정보가 은폐되어 있어 주변에 미치는 영향을 최소화 한다.
   새로운 객체의 종류를 추가 시에는 속성, 상속을 통하여 기존의 기능을 활용하고 존재하지 않는 새로운 속성만 추가하면 되므로
   매우 경제적이며 안정적이다.
 - 점진적(incremental) 프로그램 개발의 용이성, 요구사항 변화에 대해 안정된 프로그램 구조 등의 장점이 있다.

2.2. Java 특징
 1. 확장성(scalability)
     언어가 다르더라도 적용 가능하다. 예를 들어 C나 C++라이브러리 사용이 가능 , C++의 경우 해당 메소드 앞에 'native'라고
     선언해 주면 사용이 가능하다.
 2. 보안성(security)
     네트워크를 통해 PC로 다운로드 된 자바 프로그램은 일반적으로 그 능력이 제한된다. 바이러스처럼 작용할 수 없다.
 3. 이식성(universality)
     OS에 종속되지 않는다.
 4. 재사용성(modularity)
     재사용이 가능한 객체를 만들어 다른 프로그램 내에서 재사용이 가능하다.
5. 은닉(encapsulation)
     공개된 메소드를 통해서만 접근이 가능하여 class내부가 어떻게 구현되어 있는지 숨길 수 있다.

2.3. Java 기초 용어 정의
 1. Thread
    프로세스 내에서 독립적으로 실행하는 모듈로써 혼자서 자신의 고유의 일을 할 수  있는 프로그램 안의 프로그램이다.
    장점으로는 시스템 부하 없고 코드/data 공유가 가능하다.
 2. Garbage Collection
    혼자서 실행되면서 자신의 일, 즉 사용되지 않는 메모리 반환
 3. object
    class는 공통 속성(attribute), 연산(operation), 메소드(method), 관계(relationship), 행위(behavior)를 공유하는 객체의 집합
    이며, class를 근거로 실제 프로그램에서 사용 될 수 있는 형태로 메모리 위에 올린 것이다.
 
 ex) 클래스명 : 계좌
     명사 : 계좌번호, 비밀번호, 잔고, 이율, 이체한도 등…
     동사 : 입금하다, 출금하다, 조회하다 등…

     public class Account {
         private String accountNum = “123-456-789”;
        
         public long SaveMoney(long amount) {
             restMoney = restMoney + amount;
             return restMoney;
         }
     }
    
     public class MyAccount {
         public static void main(String args[]) {
             Account account = new Account();
             Account.SaveMoney(10000);

         }
     }

 4. J2SE
    Java 2 Standard Edition 약자로 자바의 중요한 부분과 필요한 라이브러리들이 포함.
 5. J2EE
    Java 2 Enterprise Edition 약자로 웹 애플리케이션 관련 기술 등으로 자바 개발을 할 수 있는 라이브러리들이 포함.
 6. J2ME
    Java 2 Micro Edition 약자로 컴퓨터뿐만 아니라 가전제품이나 휴대폰, PDA 등에 응용 프로그램을 개발할 수 있는 라이브러리들이 포함.
 7. JNI(Java Native Interface)
    다른 언어로 작성된 프로그램을 자바에서 실행할 수 있게 연결해주는 인터페이스.

   1. 장점
     - 자바에서 구현할 수 없는 기능을 구현하게 해줌
     - 각 언어의 장점을 이용할 수 있음
   2. 단점
     - 플랫폼의 독립성을 잃어버림
     - 플랫폼이 바뀌면 코드의 재사용성도 잃어버림
     - 언어별 데이터 형의 차이를 일일이 수정해야 함
     - 여기서는 언급이 안된 예외처리부분도 신경을 써야 함

 8. JVM에서의 메모리구조
   응용프로그램이 실행되면, JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.

   1. 메소드 영역(Method Area)
     - 자바 프로그램을 구성하고 있는 클래스의 메소드에 대한 바이트코드 또는 클래스의 전역변수인 클래스변수 등이 위치
   2. 스택(Stack)
     - 메소드가 호출되어 수행될 때, 메소드가 갖는 매개변수, 메소드 내에 선언된 지역변수, 임시변수, 반환치 등을 저장하기 위한 저장공간
     - 메소드의 매개변수, 지역변수, 임시변수, 반환치 등은 메소드가 호출되어 수행될때만 필요하므로 메소드 호출과 함께 이들을 
       저장하기 위한 메모리 공간(스택 프레임)이 할당되고, 메소드의 수행을 마치고 호출한 쪽으로 되돌아 갈 때, 더 이상 필요
       하지  않으므로 할당되었던 스택 프레임은 다시 시스템에 반환
   3. 힙(heap)
     - 프로그램 실행 중 생성되는 인스턴스는 모두 이 곳에 생성된다. 즉, 자바에서 객체를 저장할 때 사용하는 메모리 공간으로서,
       주로 연산자 new를 이용 하여 생성된 객체들이 저장되는 공간

2.4. Java 기본 프로그래밍 정의
 1. 배열
   Array를 object 형태로 저장된다.
   - reference변수가 필요.(선언시 사이즈 지정 안함.)
   - Array를 object를 가리킬 reference 변수를 만든 후 실제 array object를 만든다.

 public class Array {
     public static void main(String args[]) {
         int arr[]; // reference변수 선언
           arr = new int[10]; //array object 만들고, reference변수에 대입

           for(int i=0;i<arr.length;arr++) {
               arr[i] = i;

           }
       }
   }

 2. 변수 권한
   - public : 어는 calss에서나 참조 가능.
   - protected : 같은 package 내의 class 에서만 참조 가능. 자식 class가 다른 package에 있을 경우, 그 자식 class도 참조 가능.
   - default : 같은 package 내의 class만 참조 가능.
   - private : 같은 class 내에서만 참조 가능.


 3. this 키워드 : 자신의 object를 가리키는 reference


 4. == , equals() 메소드
   간단히 말하면, "=="은 연산자고 "equals()"는 메소드 이다. "=="에 대한 정의는 jvm에 있을 것이고, "equals()"에 대한 정의는 class에서 되어있다.

   == : (주소값)primitive data type 비교
   equals() : 실제 값 비교

  int i = 10, j = 20; 의 코드가 실행되었다면, i라는 변수는 10이라는 값을 가지게 된다.
  물론, j는 20이라는 값을 가지게 된다. 그런데,    String str0 = "TEST", str1 = "테스트";
  라고 하면, str0는 "TEST"라는 객체를 가리키는 참조값을 가지게 된다.
  위에서 용어를 다르게 사용했다. "값을 가진다"와 "참조값을 가진다"
  객체는 직접 접근할 수 없다. 단지, 그 위치를 참조하는 참조값을 가지고 접근하는 것 뿐이다.
  다시 본론으로가면, "=="은 그 변수가 같은 값을 가지고 있는지만 체크하는 것이다.

  int i = 10, int j = 20;
  int k = 10;
  String str0 = "TEST", str1 = "테스트";
  String str2 = new String("TEST");
  String str3 = "TEST"

  위의 코드를 수행하면, 메모리에는 다음과 같은 표의 상태가 된다.


    --------------------------------------
    |변수명| 변수값        | 실제값        |
    --------------------------------------
    | i        | 10             | (10)          |
    --------------------------------------
    | j        | 20             | (20)          |
    --------------------------------------
    | k        | 10             | (10)          |
    --------------------------------------
    | str0    | 0x3a3...(?) | [String]TEST  |
    --------------------------------------
    | str1    | 0xe1e...(?) | [String]테스트|
    --------------------------------------
    | str2    | 0xe2b...(?) | [String]TEST  |
    --------------------------------------
    | str3 | 0x3a3...(?) | [String]TEST  |
    --------------------------------------

 5. 상속(inheritance)
   메소드 overriding 해야하며 return type, 메소드 name, argument list가 일치해야 한다.


   class Employee {
       String name;
       Date hireDate;
       Date dateOfBirth;
       long salary;

       long bonus() {
           return (long) (salary * 1.5);
       }
   }

   class Manager extends Employee {
       String department;
     Employee subordinates[];

       long bonus() {
           return (long) (salary * 2.5);
       }
   }

 6. static 키워드
   static이 붙은 멤버는 class가 instance화, 즉 object로 만들어지지 않고도 사용 할 수 있다.
   Static 메소드 안에서는 static 변수만 사용 가능하다.

 7. 추상 class
   - 선언부만 있지 실제 body가 존재하지 않는 메소드를 가지고 있는 class
   - 추상 메소드가 한 개라도 있으면 추상 class로 선언해야 한다.
   - 추상 class는 instance될 수 없다.
   - 사용법
     추상 class를 상속 받아 새로운 class로 만든 후 새로이 생성된 class를 instance 한다. 
     새로 만들어진 자식 class는 부모인 추상 class의 추상 메소드를 overriding 해서 반드시 재정의 해야 한다.

    public abstract class TestAbstract {
        public abstract void func1(); //추상 메소드

        public void func2() {
            System.out.println(“일반 method”);
         }
     }

    class Child extends TestAbstract {
        public void func1() { //abstract method overriding
            System.out.println(“Hello~!”);
        }
    }

 8. 인터페이스
   서로 관계가 없는 객체들이 상호 작용을 하기 위해서 사용하는 방법. 재사용성과 호환성이 매우 높은 프로그램을 만들 수 있다.
   추상 클래스는 일반 매소드를 가질 수 있지만 인터페이스는 추상 메소드만을 가진다.
   또한, 선언하는 변수는 무조건 static final 이 붙는다.
  
   - 서로 관계가 없는 class들 사이의 유사한 특성들을 부자연스러운 클래스 관계를 설정하지 않고 얻어내야 하는 경우.
   - 하나 또는 그 이상의 클래스들에서 똑같이 구현 될 것 같은 메서드를 선언해야 하는 경우.
   - 클래스 자체를 드러내지 않고 객체의 프로그래밍 인터페이스를 제공해야 하는 경우.

   [예1]
   interface Test {
       public static final int xxx = 7;
       int yyy = 8;
  
       public void func1();
       public void func2(); 
   }

     
   class Child implements Test {
         public void func1() {
             System.out.println(xxx);
         }
 
         public void func2() {
             System.out.println(yyy);
         }
   }

     public class TestInter {
         public static void main(String[] args) {
             Child c = new Child();
             Test t = new Child();
             c.func1();
             t.func2();

             System.out.println(Test.yyy);
         }
     }

     [예2] 다중 상속기능

     interface Test1 {
         public void func1();
     }

     interface Test2 {
         public void func2();
     }

     class Child1 implements Test1, Test2 {
         public void func1() {
             System.out.println("Class Test1");
         }
    
         public void func2() {

             System.out.println("Class Test2");
         }
     }

     public class TestInter1 {
         public static void main(String[] args) {
             Child1 c = new Child1();
             c.func1();
             c.func2();
         }
     }

 9. ThreadLocal
 Java 에서 ThreadLocal 은 현재 수행되고 있는 각각의 Thread 상에서 고유한 저장소를 제공해 주는 클래스로 싱글턴 구현이나 프레임워크에서 환경변수 공유 등에 유용하게  사용될 수 있다. get 메소드 또는 set 메소드를 사용해 액세스 하는 thread가 각각 독자적으로, 변수의 초기화된 카피를 갖는다고 하는 점으로써, 통상의 변수와 다르다. 통상 ThreadLocal 오브젝트는, 상태를 thread에 관련 지으려고 하는 클래스에서의 private static 변수이다. 각 thread는 , thread가 생존 하고 ThreadLocal 오브젝트가 액세스 가능한 사이는 ThreadLocal 의 카피에의 암묵적인 참조를 보관 유지한다. thread가 종료하면(자), thread의 ThreadLocal 변수의 카피는, 모두 GC 된다.


 

by 이종화 | 2007/02/12 19:45 | JAVA | 트랙백(1) | 덧글(0)
트랙백 주소 : http://ingenuity.egloos.com/tb/3097433
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from 上善若水 at 2008/10/31 18:08

제목 : 내 손안의 PC - 자바가 구원투수가 되어야 하지 ..
세상은 카메라/GPS/3G Network을 탑재한 애플의 iPhone, 구글의 Android폰을 기점으로 완전히 새로운 세상으로 바뀌고 있습니다. ...more

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >