1. 자바를 시작하기 전에

 

* Java 의 특징

> OS 에 독립적 -> Write once, run anywhere

> Object-Oriented Language

> Garbage Collection

> Multi-Threading

> Dynamic Loading
    : 필요한 시점에 클래스를 로딩하여 사용

 

* Java 의 단점

> 속도가 느리다
    : Byte Code -> Machine Language
      (이전보다는 JIT Compiler 와 Hot Spot 같은 기술로 인해 많이 향상 되었다)

 

* Java 프로그램의 실행 과정

>  Hello.java -> (javac.exe) -> Hello.class -> (java.exe) -> 실행

 

* JDK/bin 에 있는 실행 파일들

> javac.exe

:  자바 컴파일러 (src -> byte code)

> java.exe

: 자바 인터프리터 (byte code 를 해석하고 실행)

> javap.exe

: 자바 역어셈블러 (byte code -> src)

> appletviewer.exe

: HTML 문서에 삽입되어 있는 애플릿을 실행

> javadoc.exe

: src 의 주석을 이용하여 API 문서와 같은 형식의 문서를 자동으로 생성

> jar.exe

: *.class 파일과 실행에 관련된 파일을 하나의 ajr 파일로 압축하거나 해제

 

* JDK 와 JRE

> JRE (Java Runtime Environment; 자바 실행 환경)

: JVM + Java API (Class Library)

> JDK (Java Development Kit; 자바 개발 도구)

: JRE + 개발에 필요한 파일 (javac.exe 등)

 


2. 변수

 

* Java 변수 타입

> Primitive Type

: 실제 data 를 저장

> Reference Type

: Object 의 Address 를 저장

 

* Auto boxing (>= JDK 1.5 )

> object class 와 wrapper class 간에 type casting 이 가능하다

 

* 자료형의 크기

> char (2byte)

: Unicode 를 사용

> byte (1byte)

 

* 문자형과 덧셈연산

> 문자열 + any type => 문자열 + 문자열 => 문자열

> any type + 문자열 => 문자열 + 문자열 => 문자열

 

* Type Casting

> boolean 을 제외한 7개의 기본형은 서로 Type Casting 이 가능하다

: byte, short, char, int, long, float, double)

> 표현 범위가 작은 자료형에서 큰 자료형으로 변환시에는 값 손실이 없으므로 Cast 연산자 생략이 가능하다

: char <-> short 는 모두 2byte 지만, char 는 unsigned 이므로 cast 연산자가 필요하다)

: 표현 범위 (from -> to)

- Large -> Small : 불가능

- Small -> Large (unsigned) : 불가능

- Same -> Same (unsigned) : 불가능

- Small -> Large : 가능

- Long -> float : 가능 

(Long 은 8byte, Float 는 4byte 지만, float 의 표현 범위가 long 보다 크기 때문이다)

> 4byte 이하의 자료형끼리의 연산의 결과는 Integer 가 된다

: e.g. char + char = int

 


3. 연산자

 

* 증감 연산자

> ++, -- 등의 연산자를 사용하는 경우 type casting 이 발생하지 않는다

 

* 2개의 식에 대한 성능 비교 (++i vs i = i + 1)

> 컴파일 된 후에, 전자의 명령어가 훨씬 simple 하다

> ++i

: istore_1 -> iinc 1 1

> i = i + 1

: istore_1 -> iload_1 -> iconst_1 -> iadd -> istore_1

 

* 비트 전환 연산자 (~)

> char, int 형에만 사용 가능

 

* 산술 연산자

> 모든 이항 연산자는 연산을 수행하기 전에

- 크기가 4byte 이하인 자료형 (byte, char, short)을 int 형으로 변환한다 (But, literal & 상수 간의 연산에서는 값이 casting 되지 않는다)

- 피연산자들의 타입을 서로 일치시킨다

 

* 하루를 초로 나타내기 (86,400 vs 60 * 60 * 24)

> 2가지 식 모두 컴파일 시, 86,400 으로 변환되기 때문에 가독성 측면에서 후자가 더 좋다

 

* 쉬프트 연산자

- "<<"
    : 빈칸을 0으로 채움

- ">>"

: 빈칸을 1로 채움 (부호 유지를 위해)

- ">>>"

: 빈칸을 0으로 채움

 

* 논리 연산자

> && 이 || 보다 우선순위가 높으므로 주의하여야 한다

 


4. 조건문과 반복문

 

* Label 붙은 반복문

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

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

        System.out.println( i + " " + j);

        if (i * j == 16) {

            break Loop1;

        }

    }

}

 


5. 배열

 

* 배열 선언

int[] arr1 = {1, 2, 3, };

int[] arr2 = new int[] {1, 2, 3, 4, 5}; // 크기 지정 불가

int[] arr3; // 크기 지정 불가

int[] arr4[]; // 2차원 배열

int[] arr5[] = new int[3][]; // 2차원 배열

 

* 가변 배열

int[][] score = new int[5][];

score[0] = new int[4];

score[1] = new int[3];

score[2] = new int[2];

 


6. 객체지향 프로그래밍1

 

* 객체 지향 언어

> 가장 큰 장점은 '코드의 재사용성이 높고 유지보수가 용이'하다는 것이다

- 재 사용성

- 유지보수

- 중복 제거

 

* Class Variable (Static)

> Program 이 실행되어 Class 가 Memory에 올라가면 할당되어 종료될 때 같이 소멸됨

 

* Return

> return 문을 여러 번 쓰는 것보다 method 마지막에 한 번만 사용하는 것이 좋다

 

* JVM 메모리 구조

 

* Member Variable 의 3가지 초기화 방법

1. Explicit initialization (기본적인 초기화 방법)

2. Constructor

3. Initialization Block (초기화 블럭)

 

public class Initialization {

 

static {

// 클래스 초기화 블럭 - 복잡한 초기화에 사용

}

 

{

// 인스턴스 초기화 블럭 - 복잡한 초기화에 사용

}

}

 

* Class Loading 과정

 

* this()

> 다른 생성자에서 호출할 때는 반드시 첫 줄에서만 호출 가능하다

: 다른 생성자를 호출하게 되면 변수들을 초기화하는 작업이 꼬이는 것을 방지하기 위해 막아둠

 

* this

> 참조 변수로 자기 자신을 가리킴

> 생성자를 포함한 모든 인스턴스 메소드에는 this 가 지역변수로 숨겨진 채 존재한다

 


7. 객체지향 프로그래밍2

 

* 상속

> 생성자와 초기화 블럭은 상속되지 않는다

> 자손의 접근 제어자는 부모의 접근제어자보다 범위가 좁을 수 없다

: public > protected > package private (=default) > private

> 자손에서 Overriding 된 메소드 예외처리의 범위는 조상 메소드보다 좁아야 한다

: Exception > XXXException

- Parent 로 대체되어도 정상 동작되어야 하기 때문에

> Instance Method <-> Static Method 간 변경이 불가능하다

 

* super & this

> 조상에서 상속받은 변수는 2개다 사용가능하다

 

* import 문

> import aaa.bbb.*; 해도 성능상에서 차이는 없다. 다만, 명시적으로 지정했을 때와 비교해서 컴파일러가 해당 패키지에서 특정 클래스를 찾기 위한
    수고가 필요하다

> 아래와 같은 패키지 구조가 있을 때, aaa.*; 한다고 해서 하위 패키지의 class들까지 import 하는 것은 아니다

import aaa.bbb.*;

import aaa.*;

 

* final 변수

> 명시적 초기화, 즉 선언과 동시에 대입이 가능하다

> 생성자에서 대입이 가능하다

> 초기화 블럭에서 대입이 가능하다

- {}

 

* Access Modifier (접근 제어자)

> abstract + static = 불가능

> abstract + final = 불가능

> abstract + private = 불가능

> private + final = 불가능

 

* Class Type Casting

> Up-Casting - 생략 가능

> Down-Casting - 생략 불가능

 

* interface

> 추상화 정도가 높아서 일반 메소드 및 멤버 변수를 가질 수 없는 추상 클래스

> Class 와 달리 다중 상속이 가능

> public static final 변수 + public abstract method 만 가질 수 있다

> 장점

: 개발 시간 단축

: 표준화 가능

: 독립적인 프로그래밍

 


8. 예외처리

 

* Error

> 프로그램 코드에 의해서 수습될 수 없는 심각한 오류

 

* Exception

> 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류

 

 

 

* RuntimeException

> try-catch 를 이용하기 보다는 예외가 발생하지 않도록 처리

 

* 에러 로그 출력

> Default 로 화면에 로그를 출력

: System.out();

: System.err();

> 파일에 로그를 출력

PrintStream ps = new PrintStream("error.log");

//파일에 출력1

ps.println("error occurs!!!!"); 

 

// 파일에 출력2 (System.err() 실행 시, printStream에 정의된 파일에 로그 출력)

System.setErr(ps); 

 

* void method() throws Exception

> 이 메소드를 호출하는 경우에는 exception 처리가 필요하다는 것을 의미

> 일반적으로 RuntimeException 인 경우에는 적지 않는다

 

* try-catch-finally 실행 과정

> 예외가 발생하지 않은 경우

: try -> finally

> 예외가 발생한 경우

: try -> catch -> finally

> System.exit(0) 가 호출되는 경우

: 이 경우에는 바로 종료된다

> try or catch 에 return 이 있는 경우

: try/catch 에 return 문이 있더라도 finally 블럭을 수행한 후에 return 문을 실행

> catch 블럭에서 새로운 Exception 발생하는 경우

: 기존 try-catch 의 finally 블록은 그대로 수행

> catch (Exception e) 블럭의 경우, catch 블럭 중 가장 마지막에 위치하여야 한다 (그렇지 않으면, Compiler Error 가 발생)

 


9. java.lang 패키지

 

* java.lang 패키지

> 가장 기본 패키지로써 import 없이도 사용가능하다

 

* Object

> hashCode()

: 주소값을 hash 로 반환

> clone()

: instance, array 변수 등을 제외한 member 값만 복제

- 같은 array 주소를 갖게 되면 src 객체의 배열값에 영향을 미치게 된다

: cloneable 인터페이스를 implements 한 class 에서 사용 가능

> finalize()

: GC 에 의해 자동적으로 호출된다

 

* String

 

* Wrapper

Integer.parseInt("100", 2); // 100 값을 2진수로 변환 (=4)

Integer.parseInt("100", 8); // 100 값을 8진수로 변환 (=64)

Integer.parseInt("100", 16); // 100 값을 16진수로 변환 (=256)

Integer.parseInt("FF", 16); // FF 값을 16진수로 변환 (=255)

 


10. 내부 클래스

 

* Inner Class

> Inner Class 에서 Outer Class 에 쉽게 접근 가능하다

> 외부에 불필요한 class 를 감춰 code 의 복잡성을 줄일 수 있다 (캡슐화)

: 외부에서 사용하지 않는 경우, inner class 를 사용한다

 

* 클래스 파일 생성 경로

public class Outer {

    

void method1() {

class LocalInner {}

    }

 

void method2() {

class LocalInner {}

    }

    

void method3() {

new LocalAnnonymous() {

void annonymousMethod1() {}

        };

}

 

void method4() {

new LocalAnnonymous() {

void annonymousMethod2() {}

        };

}

}

 

> Outer.class

> Outer$1LocalInner.class

> Outer$2LocalInner.class

> Outer$1.class

> Outer$2.class

 


11. 컬렉션 프레임웤과 유용한 클래스

 

* Collections

 

* Shallow Copy (얉은 복사)

> 배열이나 객체를 복사할 때, 단순히 참조만 복사

 

* Deep Copy (깊은 복사)

> 원본과 같은 데이터를 저장하고 있는 새로운 객체나 배열을 생성하는 것

 


12. 지네릭스, 열거형, 애너테이션

 

*


13. Thread

 

* Thread


14. 람다와 스트림

 

 


15. 입출력 I/O

 

* AWT, Swing, Applet

 

* Stream

 

* 표준입출력

   > System.in : InputStream (BufferedInputStream)

   > System.out,err : PrintStream (BufferdOutputStream)

      - 버퍼가 있기 때문에 커서를 통해 Backspace 사용 가능

   > setOut(), setErr(), setIn()

      - Argument로 I/O Stream을 변경

 

* File

  > Canonical Path

     - 기호나 링크 등을 포함하지 않는 Unique Path

       : /root/file.dat

  > Absolute Path

     - Root부터 시작하는 파일의 Full Path

       : /root/file.dat

       : /root/./file.dat

 

* Serialization


16. 네트워킹

 

* Server-based Model

  > 네트워크를 구성할 때 전용서버를 둠

 

* P2P (Peer-to-Peer) Model

  > 서버와 클라이언트 역할을 동시에 수행

 

* URL (Uniform Resource Location)

  > Protocal://hostName:portNumber/path/filename?query#anchor

  > Protocal : 자원에 접근하기 위해 서버와 통신하는데 사용되는 통신규약

  > Host Name : 자원을 제공하는 서버의 이름

  > Port Number : 통신에 사용되는 서버의 포트번호

  > Path : 접근하려는 자원이 저장된 서버상의 위치

  > File Name : 접근하려는 자원의 이름

  > Query : URL에서 '?' 이후의 부분

  > Anchor : URL에서 '#' 이후의 부분

 

* Socket

  > Process 간 통신에 사용되는 양쪽 End Point

  > I/O Stream 을 가지고 있다

* Server Socket

  > Port 와 Bind 되어, 외부 연결을 기다리다가 연결 요청이 들어오면 Socket을 새성해서 Socket 간 통신이 이루어진다

  > 한 Port에 하나의 Server Socket만 연결 가능 (Protocol 이 다르면 같은 Port 공유 가능)

+ Recent posts