Java language specification 정리

Java language 설명서
http://jkkang.net/Java/Manual/javaspec.html

1.2.4.1 정수 표현(integer LIterals)

정수형은 10진수, 16진수, 8진수로 표현할 수 있다.
10진수는 (0~9)까지의 값을 가지고 접두어는 생략한다.
16진수는 (0~9, A~F)까지의 값을 가지고 접두어로 '0X 또는 0x'를 붙힌다.

8진수는 (0~7)까지의 값을 가지고 접두어로 '0'가 붙는다.


1.2.4.2 실수 표현(Floating Point Literals)

실수형 표현은 "."을 이용하여 소숫점이상, 이하를 표현한다. 'E 또는 e'를 사용하여 지수를 표현한다. 다음은 모두 올바른 실수형의 표현이다. 
3.1415 3.1E12  .1e12  2E12

1.3 자료형(Types)

Java language에서는 두가지 simple, composite 형태의 자료형이 있다.
Simple type은 atomic하기 때문에 절대 손상되지 않는 type으로 integer, floating point, boolean, charter 등이 있다.
Composite type은 simple type으로 구성된 자료형으로, array, classes, interface 3가지가 있다.

1.3.3 배열. (Array)

배열은 언어에서 first class object이다. 배열은 new 연산자를 사용하여 생성한다. 
char s[] = new char[30];

Multi-dimensional 배열은 제공되지 않는다. 대신, programmer는 배열의 배열을 정의할 수 있다.
int i[][] = new int[3][4];

배열의 배열에서 배열의 크기는 최소한 하나는 명시되어야 한다. 명시되지 않은 부분은 다음에 명시적으로 크기를 정할 수 있다.
int i[][] = new int[3][];

Java에서는 C에서의 대괄호를 이용한 배열선언의 확장된 표현이다.
다음 두 방법은 모두 올바른 배열 선언 방법이다.
int iarray[];
int[] iarray;

1.3.3.1 배열의 내부구조. (Array Detail)

Array는 Object class의 subclass의 instance이다.
모든 type의 배열은 Array의 subclass이다. 즉, 다음의 Thread의 배열은
new Thread[n]


Thread[]의 instance를 생성한다.

마찬가지로 다음 그림에서 class A가 class B의 superclass 이면 A[]는 B[]의 superclass이다.

그러므로, 배열에는 Object를 대입할 수 있다.

Object o;
int a[] = new int[10];
o = a;

또한 Object를 배열로 형변환(cat)할 수 있다 (Array class는 형변환 연산자를 명시해야 한다)

a = (int[])o;



1.4 클래스. (Classes)

Class는 고전적으로 객체지향 프로그래밍 model을 표현하는데 사용되었다. 데이타 추상화(Data abstraction)화 data를 엮는 역할 을 한다.

Java에서 class를 생성한다는것은 새로운 type을 생성하는 것을 의미한다.

모든 class는 하나의 root class로부터 파생된다.

Object를 제외한 모든 class는 하나의 직속 superclass를 가진다.
만약 class가 직속 superclass를 정의하지 않으면, superclass는 Object로 간주된다.

예를 들어서 다음 code는 같은의미이다.

class Point {
    float x, y;
}

class Point extends Object {
    float x, y;
}

Java에서는 오직 하나의 class로부터의 상속(simgle inheritance)만을 허용한다.

다른 언어에서 제공하는 다중 상속은 interfaces를 이용하여 극복할 수도 있다.

1.4.1 Class의 형변환. (Casting Between Class Types)

Java는 형변환을 제공한다.
또한, class는 하나의 새로운 type이기 때문에 class type간의 형변환을 제공한다.
만약 B가 A의 subclass라면, B의 instance는 A의 instance로 사용될 수 있다.

형변환 연산자가 필요없지만 명시하는것이 좋다. 이것을 'widening' 이라고 부른다.


만약 A의 instance가 B의 instance처럼 사용될 필요가 있다면 형변환이 가능한데 이것을 'narrowing'이라고 한다. 그 일반적인 표현은 다음과 같다.

(classname)ref

ref는 classname으로 형변환 된다.

형변환은 단지 참조하기 위해서만 쓰이고, object자체가 변하는것은 아니다. 



1.4.2 메소드. (Methods)

Method는 object나 class이 수행하는 일(연산)을 표현한다.
Method는 class나 interface에서 선언할 수 있으나, 오직 class안에서만 일을 수행 할 수 있다. (모든 사용자 정의 연산(user-defined operation)은 method로 구현된다.)

Java는 overriding과 overloading기법의 polymorphic method를 제공한다.


overriding은 superclass로 부터 상속받은 같은 method를 대신하여 다른일을 하는 같은 이름의 새로운 method정의 하는것을 의미한다.


overloading은 method가 오직 이름만 같고 서로 다른 method를 사용하는 것을 의미하며, parameter list로 같은 이름의 method를 서로 구별할 수 있다.

단, return type으로는 구별하지 않는다. 


1.4.2.1 Instance Variables.

method의 내부에 정의되지않고, static이 아닌 모든 변수는 instance vairable이다.
Instance variable은 modifier를 가질 수 있다. 

Instance variable은 어떤 type이어도 되고, 초기화할 수 있다.


만약 초기화 되지 않으면 0으로 초기화된다, boolean은 false, object는 null. 



1.4.2.3 Setting Local Variables.

Method는 local variable을 참조하여 사용하기 전에 초기화 되었는지 엄격하게 검사한다.
초기화하지 않고 local variable을 사용하게 되면 compile-time error를 발생시킨다. 


1.4.3 Overriding Methods

Method를 override하기 위해서, 원래의 method를 가지고 있는 class의 subclass는 이름이 같고, parameter, return type도 같은 method를 정의해야 한다.


1.4.4 Overload Resolution.

Overloaded method는 argument의 갯수나, argument의 type이 다른 같은 이름의 method를 말한다.
Overload resolution은 어떤 overloaded method를 호출 할것인지 결정하는 일을 한다.

method는 같은 class안에서도 overload할 수 있다.class내에서 method의 선언 순서와는 전혀 무관하다.


Aargument의 갯수나, type을 다르게 함으로써 method를 overload한다. Compiler는 대응되는 최소한의 비용으로 method를 를 찾는다.


오직 같은이름의 같은수의 argument와 같은 type의 argument를 가지는 method를 찾는다.



1.4.5 생성자. (Constructors)

생성자는 초기를 위해 특별히 제공되는 method이다.
return 값이 없고, class의 이름과 같으므로 다른 method와 구별된다.

생성자는 object가 생성될때 자동으로 호출된다.

생성자는 표면적으로 호출 할수는 없다.
만약 package 외부에서 생성자를 호출할 필요가 있다면, 생성자를 public으로 해야한다. 


1.4.6 new연산자를 이용한 객체 생성. (Object Creation-the new Operator)

Class는 object의 상태와, 행동방식을 정의한 template이다.
Object는 class의 instance이다.

모든 class의 instance는 garbage collected heap에 할당된다.

Object의 선언만으로는 메모리를 할당하지 않는다.
Programmer는 object를 위한 메모리 할당을 명시해야만 한다.

그러나, 명시적인 메모리 반납은 필요없다. 왜냐하면, garbage collector는 더이상 필요가 없을깨 자동으로 메모리를 정리한다.



1.4.6.1 쓰레기정리. (Garbage Collection)

Garbage collector는 간단하고 강력한 메모리 관리자이다. Program에서는 명시적인 메모리 반납을 절대 필요하지 않는다.; 자동으로 처리해준다.

Garbage collector는 여전히 참조되는 메모리는 절대 반납하는 경우가 없고, 더이상 쓰이지 않는 메모리는 항상 반납한다.


이것은 dangling pointer bug와 storage leak를 근절시킨다. 또한, designer로 하여금 system적인 메모리 관련부분을 신경쓰지 않도록 해준다.



1.4.6.2 The null Reference.

예약어 'null'은 "no instance"를 나타내는 상수값이다.
null은 어떠한 instance에도 적용이 되며, 어떠한 class type으로도 형변환이 가능하다.



1.4.7 Static Methods, Variables, and Initializers.

Class에서 variable과 method는 static으로 선언될 수 있다. 이것은 class의 instance를 위한것이라기 보다는, class 자체를 위한 것이다. 또한, class 내부 code의 block도 static으로 정의할 수 있다. 이것을 static initializer라고 한다.

Static variable은 instance variable처럼, initializer를 가질수 있다.

Static variable은 instance의 수에는 상관 없이 오직 class에 하나씩만 메모리 할당이 되어 공유한다. Static variable과 static method는 둘다 class의 이름을 이용하여 접근할 수 있다.
또한 class의 instance를 이용해서도 접근할 수 있다.



1.4.7.2 초기화 순서. (Order of Initialization)

Class가 load될때, ㅁ모든 static initialization code가 실행 된다.

Static initializer는 static variable이 초기화 되는것과 같은 시간에 실행된다. 초기화는 어휘순서로 처리된다. 다음은 class C를 선언한 것이다. 

    class C {
        static int a = 1;
        static {
            a++;
            b = 7;
        }
        static int b = 2;
    }


class C가 load될때 다음의 순서로 이루어진다.

  • a가 1로 초기화 된다.
  • static initializer가 실행되어, a는 2, b는 7로 초기화한다.
  • b를 2?로 초기화한다.

만약 load되지 않은 class의 static initialization code가 다른 load되지 않은 class로를 참조하면, 이 참조되는 class는 load되어서 제일먼저 자신의 static initialization code를 실행한다.
이때 참조되는 class의 static initialization code에서 다시 load되지 않은 class를 참조하게 되면, cycle이 생성되어, NoClassDefFoundException이 실행된다.


다음은 static variable의 초기화 과정에서 forward dependency에 따른 compilie-time error 예제이다.

    int i = j + 2;
    int j = 4;

instance variable의 초기화 에서 static vaariable에 따른 forward dependency로 보이는 예제이다.
    int i = j + 2;           // Instance variable
    static int j = 4;        // Static variable

위에서, i는 j에의해서 forward dependency처럼 보이나, i는 6으로 j는 4로 초기화 된다. 왜냐하면 static variable인 j가 instance variable인 i보다 먼저 초기화가 되기 때문이다.

Static method는 instance variable을 참조 할 수 없다. 오직 static method와ㅏ staatic variable만을 참조 할 수 있다.

1.4.9 Varable Scoping Rules.

Class가 subclass로 정의될 때, package내에서 superclass의 선언된 내용은 subclass내에서 볼 수 있다. method내에서 선언된 variable은, 다음의 scoping 규칙에 따른다.
  1. 제일먼저 현재 block을찾고, 현재 method에 둘러싸인 전체 block을 잦는다. 이것은 local scope에 관한 이야기.
  2. 현재 class의 variable을 찾는다.
  3. 만약 variable을 찾지 못하면, 가장 가까운 superclass로부터, 모든 superclass의 variable 에서 찾아서 Object class까지 올라간다.
    그래도 찾지 못하면, Import된 class와 package를 찾는다. 그래도 못찾으면, compile-time error를 내보이게 된다.
같은 class내에서 같은 이름의 multiple variable은 허용하지 않고, compile-time error를 내보낸다.

1.4.10.1 Threadsafe Variables.

Instance variable 또는 static variable은 'threadsafe'라고 명시하여, 한 thread가 변수를 사용하고 있을때, 다른 thread가 접근하여 값을 절대 부꾸지 못하도록 보호하여야 한다.(변수값 비동기적으로 바꾸지 못하도록한다.)
Primary optimization은 threadsafe를 이용하여 instance variable을 register에 caching을 한다.


1.4.10.2 Transient Variables.

'transient' flag는 interpreter로 하여금, class의 instance를 persistent object로 처리하도록 한다.

1.4.10.5 Abstract Methods.

Abstract method는 subclass들간의 규약을 정하기 위한 superclass 또는 interface의 기능을 제공한다. Abstract method는 subclass에서는 반드시 정의를 해야 한다. Abstract method는 method body가 없고, 대신 선언은 semicolon 으로 끝난다.

'abstract' keyword는 다음과 같은 규칙을 가지고 있다.
  • Constructor는 abstract 할 수 없다.
  • Static method는 abstract 할 수 없다.
  • Private method는 abstract 할 수 없다.
  • Abstract method는 abstract method가 선언되어있는 class의 subclass에 정의한다.
  • Superclass의 method로부터 override된 method는 abstract 할 수 없다.
  • Abstract method와 overriding 하지 않고 abstract method를 상속받은 class를 abstract class라고 한다.
  • Abstract class를 instantiate하거나, abstract method를 직접 호출하면 compile-time error를 내보낸다.

1.4.10.6 Synchronized Methods and Blocks.

'synchronized'는 method나 block의 code에 lock을 거는것이다. Lock은 synchronized code가, 같은 시간에 같은 resource를 access하는 서로다른 code 로 실행 되지 않도록 방지하는 것이다. 각각의 object는 하나의 lock을 가지고있다.

Synchronized method가 호출 되면, 현재 instance를 위한 lock을 얻을때 까지 기다린다. Lock을 얻은 후에는 code를 실행 시킨후 lock을 반납한다.

Synchronized block은 synchronized method처럼 수행한다. 단 다른점은, 현재의 instance나 class를 위한 lock을 사용하는대신, sysnchronized block은 object와 관련된 lock이나, class에서 제공하는 block의 synchronized 문장을 사용한다는 것이다.

Synchronized block은 다음과 같이 선언한다.

    /* ...preceding code in the method... */
    synchronized(<object or class name>) {      //sync. block
        /* code that requires synchronized access */
    }
    /* ...remaining code in the method... */

다음은 synchronized method 선언 방법이다.
    class Point {
        float x, y;
        synchronized void scale(float f) {
            x *= f;
            y *= f;
        }
    }
다음은 synchronized block의 예이다.
    class Rectangle {
        Point topLeft;
        ...
        void print() {
            synchronized (topLeft) {
                println("topLeft.x = " + topLeft.x);
                println("topLeft.y = " + topLeft.y);
            }
            ...
        }
    }

1.6.1 Specifying a Compilation Unit's Package.

Compilation unit의로의 package는 'package'문장으로 나타낸다. 이문장이 나타나면, Compilation unit에서는 non-comment, non-white space line 이어야 한다. 그형식은 다음과 같다.
package packageName;
Compilation unit에 package문장이 없으면, 이름이 없는 default package로 대치된다.

1.7.1.6 Operators on Objects.

'instanceof'는 특정 object가 특정 class또는 subclass의 instance인지 검사한다.
    if (thermostat instanceof MeasuringDevice) {
        MeasuringDevice dev = (MeasuringDevice)thermostat;
          ...
    }
Java는 labeled loop와 labeled break를 지원한다. 다음은 그 에이다.
    outer:   // the label
        for (int i = 0; i < 10; i++) {
            for (int j= 0; j< 10; j++) {
                if (...) {
                    break outer;
                }
                if (...) {
                }
            }
    }

1.8.4.1 The finally Statement.

'finally'문은 exception이 발생하더라도 몇몇 code를 실행하고 싶을때 사용한다. 'catch'문이나 'finally'문은 'try'문 다음에 사용할 수 있다. 하지만 동시에 둘을 사용할 수 없다. 다음은 그 예이다.
    try {
        // do something
    } finally {
        // clean up after it
    }
위의 code는 다음 아래의 것과 비슷하다.
    try {
        // do something
    } catch(Object e){
        // clean up after it
        throw e;
    }
    // clean up after it
'finally'문은 'try' block에서 return, break, continue, throw문을 실행 시키더라도 실행된다.
예를 들어, 다음 code의 결과는 "finally"라고 출력된다. 그러나 "after try"는 a!=10일때만 출력 된다.
    try {
        if (a == 10) {
            return;
        }
    } finally {
        print("finally\n");
    }
    print("after try\n");

1.8.4.2 Runtime Exceptions

1. Arithmetic Exception : 0으로 나눌때 발생된다. 그밖의 경우는 없다
2. NullPointerException
3.IncompatibleClassChangeException
  • class 내부의 variable의 선언이 static에서 non-static으로 바뀌었는데, 다른 class가 이 바뀐 variable을 참조할때.
  • class 내부의 variable의 선언이 non-static에서 static으로 바뀌었는데, 다른 class가 이 바뀐 variable을 참조할때.
  • class 내부의 field가 지워졌는데, 다른 class가 이 field를 참조할때.
  • class 내부의 method가 지워졌는데, 다른 class가 이 field를 참조할때.
4. ClassCastExceptionobject O가 class C로 형변환 할때,
O는 C가 아니고 C의 subclass도 아닐때 ClassCastException이 실행 된다.
5. NegativeArraySizeException
배열의 크기가 음수이면 NegativeArraySizeException이 실행된다
6. OutOfMemoryException
더이상 메모리 할당을 할수 없을때 OutOfMemorryExceptin이 실행된다.
이것은 오직 new 연산자를 이용하여 object를 생성할때만 발생된다. 
7. NoClassDefFoundExceptionClass를 참조할려고 하나, runtime system이 참조할 class를 찾지 못할때 실행 된다. class는 해당 클래스가 compile될때 이미 존재해야 한다.
8. IncompatibleTypeException
Interface의 instance를 생성할때 발생한다. 
9. ArrayIndexOutOfBoundsException
배열의 잘못된 element를 index할 경우 실행된다.

10. UnsatisfiedLinkException
Method가 native로 선언되었고, method가 runtime system routine과 더이상 연결되지 않을때 발생한다.
    class NoLink {
        static native void foo();
        public static void main(String args[]) {
            foo();
        }
    }
11. InternalException
runtime system의 이름모를 오류가 발생할때 실행된다. 이러한 경우가 발생하면 WebRunner@Sun.COM으로 연락해본다.

댓글

이 블로그의 인기 게시물

Java 관련 기초 지식들