자바의 신 3 판, VOL.1 기초 문법편 총 정리, Chapter 7 ~ 13

청주는사과아님·2024년 3월 11일
post-thumbnail

자바의 신 : VOL.1 기초 문법편 3판 총정리, Chapter 7 ~ 13


  • Java 에서의 배열

    Java 는 완전한 객체지향 언어를 목표로 설계되었다. 그래서 Java 의 다차원 배열 은 정말로 배열의 배열 이다. 배열의 배열 이기 때문에 아주 간편히 ragged array 를 만들 수 있다.

  • 배열과 같은 객체가 print 될 때 어떻게 보여질까?

  • Enhanced for loop

    JDK 5 부터 Java 에도 Enhanced for loop 를 사용할 수 있다. 쉽게 말해 Python 에서의 for 문 마냥 사용할 수 있다는 것이다.


  • 클래스의 생성자

    생성자란 어느 클래스 타입의 객체가 생성될 시, 객체의 필드 등의 초기화를 위한 메서드의 일종이다.

    Java 의 기본 생성자는 오직 compiler 에 의해서 자동으로 만들어지는 생성자이다. 기본 생성자는 클래스의 어떠한 생성자도 존재하지 않아야 생성되며, 이는 그냥 빈 생성자 형태이다.

  • 클래스 변수static block

    클래스 변수 를 초기화 하는 방법 중 static block 을 이용하는 방법이 있다. 이 때 static block 은 해당 클래스 객체가 처음 사용될 때 단 한번만 실행되는 block 이다.

    때문에 어느 클래스의 클래스 변수 가 존재할 시, 해당 클래스 타입의 객체가 다수 존재하더라도 statkc block클래스 변수 는 단 한번만 초기화/실행 되고, 해당 타입의 모든 객체가 그 클래스 변수 를 공유한다.

  • Java가변인자

    Java 에서도 가변인자 를 사용해 메서드를 선언할 수 있다. 가변인자Variable Arguments 또는 Arbitary Number of Arguments 로 불리며, 메서드 호출 시 필요한 인자의 숫자가 정해지지 않은 선언 방식을 말한다.

    가변인자배열 형식으로 주어진 매개변수 와 매우 유사하다. 하지만 그렇다고 배열 형식인 매개변수가변인자 처럼 메서드에 넘겨주는 것은 가능하지 않다.


  • Javapackageimport

    Javapackage 는 그저 폴더 의 개념 보다는 C++namespace 에 좀더 가까운 개념이다. 분명히 package 를 이용해 소스를 모듈화 시킬 순 있지만 package-private 등과 같은 namespace 의 개념이 포함되어 있다.

    package 는 소스의 최상단에 위치해야 하며, import 는 아래에 위치하여야 한다. 이를 지키지 않을 시 compile error 를 일으킨다.

    더불어 Oracle DocsPackage Naming Convention 이 언급되어 있는데, 이는 다음과 같다.

    • package 이름은 소문자로 작성한다.

    • package 이름에 Java 예약어를 사용하지 않는다. (최소한 _ 라도 넣어라)

    • packagejava 또는 javax 로 시작하지 않는다.

      덧붙여 문서에는 나와있지 않지만, 영리 단체는 com 으로, 비영리 단체는 org 로 시작해 package 이름을 붙인다는 관용이 있다.

  • import

    Java 에서 import 키워드를 이용해 특정 package 속 특정 클래스, 또는 package 속에 포함된 모든 클래스를 가져올 수 있다.

    덧붙여 JKD 1.5 이후 버전부터 import static 이 추가되었다. 이는 static 한 것들 (클래스 변수, static 메서드 등) 을 불러오고자 할 때 용이하다.


  • 상속메서드 Overriding

    Java 에도 당연히 상속 이 있고 OverrideOverload 가 있다. 이 때 상속extends 키워드를 이용해 진행할 수 있으며, implements 와 유사하지만 엄연히 다름에 유의해야 한다.

    어느 클래스를 상속 받으면 C++ 에서와는 다르게 부모의 생성자가 자동으로 상속 되지 않는다. 상속 관계가 정해졌을 시, super 키워드를 이용해 부모 클래스의 메서드, 생성자 등에 접근할 수 있다.

    부모 클래스의 메서드를 Override 할 시, 해당 메서드의 가시성 (Visibility) 는 제한될 수 없다.
    메서드의 가시성 은 다음과 같은 순서를 갖는다. (내림차순)

    • public <-- package-private <-- protected <-- private

      여기서 package-private 한 메서드는 각별한 주의가 필요하다. 왜냐하면 해당 메서드를 Override 하려해도 같은 package 가 아니라면 접근조차 안되기 때문이다.

    • package-private method 의 Override?

  • 상속 관계 클래스간 형 변환Polymorphism

    간략히 말하면 (자식 --> 부모) 로의 형변환은 가능하다. 반면 (부모 --> 자식) 으로의 형 변환은 될수도 있고 안될수도 있다.

    (부모 --> 자식) 으로의 형변환을 진행하면 runtime error 를 발생시킬 수 있다.

    • 예시 및 형변환이 제한된 이유

      이러한 형 변환은 Java다형성 (Polymorphism) 을 보여주는 한 예시이다. Java 에는 이러한 서브타입 다향성 외에도 매개변수의 다향성, 임시 다향성 등이 존재한다.

  • final 키워드

    만약 클래스에 final 키워드를 이용해 선언한다면, 해당 클래스는 더이상 상속될 수 없다.

    마찬가지로 메서드에 final 키워드를 이용한다면, 해당 메서드는 더이상 Override 될 수 없다. (Overloading 은 가능하다)


  • java.lang.Object 의 메서드

    Object 클래스는 Java 내 모든 클래스의 부모인 클래스이다. 해당 클래스에는 크게 2 종류의 메서드가 존재하고, 이는 다음과 같다.

    • 객체 처리를 위한 메서드

      Method설명
      protected Object clone()객체의 복사본을 만들어 리턴한다.
      public boolean equals(Object obj)현재 객체와 매개 변수로 넘겨받은 객체가 같은지 확인한다.
      protected void finalize()현재 객체가 더 이상 쓸모 없어졌을 때, GC (Garbage Collector) 에 의해서 이 메서드가 호출된다. 하지만 여러 문제점 때문에 JDK 9 부터 Deprecated 되었다.
      public Class<?> getClass()현재 객체의 Class 클래스의 객체를 리턴한다.
      public int hashCode()객체에 대한 hash code 값을 리턴한다. 이 때 해쉬 코드는 "16 진수로 제공되는 객체의 메모리 주소" 를 말한다.
      public String toString()객체를 문자열로 표현하는 값을 리턴한다.
    • 스레드 처리를 위한 메서드

      Method설명
      public void notify()이 객체의 모니터에 대기하고 있는 단일 스레드를 깨운다.
      public void notifyAll()이 객체의 모니터에 대기하고 있는 모든 스레드를 깨운다.
      public void wait()다른 스레드가 현재 객체에 대한 notify() 메서드나 notifyAll() 메서드를 호출할 때까지, 현재 스레드가 대기하고 있도록 한다.
      public void wait(long timeout)wait() 메서드와 동일한 기능을 제공하며, 매개 변수에 지정한 시간 만큼만 대기한다. 여기서 매개 변수 timeoutms 단위이다.
      public void wait(long timeout, int nanos)wait() 메서드와 동일한 기능을 제공한다. 해당 메서드는 timeout + nanos 시간 만큼 스레드를 대기시킨다. 이 때 timeoutms 단위이고, nanosns 단위이다.
  • 비교 연산자 == 와 equals 메서드의 차이

  • hashCode 와 System.identityHashCode 의 차이점


  • 추상화

    Java 에서 abstract"추상 클래스" (abstract classes) 또는 "추상 메서드" (abstract methods) 를 선언하기 위한 키워드이다.

    이 때 "추상" 또는 "추상화""어느 시스템의 기반을 담당하는 과정 등을 일반화하고 뭉뚱그려, 더 효율적으로 수행하기 위한 방법론" 이다. Javaencapsulation유사한 개념이라 생각할 수 있다.

    이에 대한 대표적인 예시가 추상 메서드, interface, 그리고 추상 클래스 이다.

  • 추상 메서드interface

    추상 메서드 란 선언만 되어있을 뿐 구현이 되어있지 않은 메서드를 말한다. interfaceJava 에서 추상화 를 가능케하는 키워드 중 하나로, interface추상 메서드final, static 변수 들의 집합을 선언할 수 있다.

    • 예시 및 설명

      더불어 JDK 8 부터 interfacedefault, static method 를 선언할 수 있게 되었다. 이를 이용해 좀더 유연한 추상화 가 가능하다.

  • 추상 클래스

    추상 클래스Java 에서 추상화를 가능케 하는 클래스로, interface 보다 더 유연한 추상화 가 가능하다.

  • 추상 클래스interface 의 차이점

    추상 클래스interface 는 유사한 점이 많다. 두 가지 모두 인스턴스화 할 수 없고, 추상 메서드 를 선언할 수도 안 할수도 있다. (interface - default method)

    하지만 당연히 차이점이 존재하는데, 추상 클래스static 또는 final 하지 않은 필드 를 선언할 수 있으며, public, protected, private 메서드를 만들어 사용할 수 있다.

    반면 interface 의 경우, 선언한 필드는 모두 자동적으로 public static 또는 public final 이며, 선언한 메서드 또한 모두 public 이다.

    덧붙여 추상 클래스(클래스 이므로) 단 하나의 추상 클래스extend 할 수 있으며, interface 의 경우 다수의 interfaceimplement 할 수 있다.

    위 설명을 정리하면 다음처럼 나타낼 수 있다.

    구분abstract classinterface
    field뭐든지 가능public static, public final 만 가능
    method뭐든지 가능public 메서드만 가능 (JDK 8 <= default, static method 가능)
    extend오직 1 개만 extend 가능(class 이므로) 불가능
    implement(interface 이므로) 불가능여러개 implement 가능

  • 열거형 클래스(?)

    Java 에도 열거형이 존재한다. 하지만 이는 C 의 것과는 아주 다르다. Java 는 객체지향 언어라 열거형 또한 클래스로 선언되어, enum 이 생성자, 메서드를 가질 수 있기 때문이다.

    거기다 또 한가지 큰 차이점이 있는데, C 에서는 열거형 상수가 어느 정수로 정확히 대응될 수 있는 반면, Java 는 절대 그렇지 않고 열거형 상수 또한 어느 클래스 라는 것이다.

  • Enum 클래스 와 메서드

    Java 의 모든 열거형은 java.lang.Enum 의 자식들이다. Enum 클래스 또한 java.lang.Object 의 자식이기 때문에, Object 의 메서드 또한 Override 되어있다.

    그런데 이 중, 다음 4 가지는 더이상 Override 할 수 없게 선언되어 있다.

    Method DeclarationDescription
    protected final Object clone()객체를 복제하기 위한 메서드이지만 Enum 에서 사용할 경우 CloneNotSupportedException 를 발생시킨다.
    protected fianl void finalize()GC 가 발생할 때 처리하기 위한 메서드, Deprecated
    fianl int hashCode()enum 상수에 대한 hash code 를 반환하는 메서드
    fianl boolean equals(Object other)주어진 객체가 상응하는 enum 상수인지 판별하는 메서드

    이 외에도 다음과 같은 메서드가 추가로 선언되어 있다.

    Method DeclarationDescription
    final int compareTo(E e)메서드에 주어진 enum 타입의 매개변수 (e) 와의 순서 차이 (ordinal) 를 리턴한다.
    final Class<E> getDeclaringClass()해당 enum 상수의 클래스를 나타내는 객체를 반환한다.
    final String name()해당 enum 상수의 선언된 이름을 반환한다.
    final int ordinal()해당 enum 상수의 선언된 순서를 반환한다.
    static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)주어진 enumTypename 에 해당하는 enum 상수를 반환한다. static 메서드이므로 Enum.valueOf 로 접근해 사용할 수 있다.

    마지막으로 열거형 클래스에는 values() 라는 메서드가 존재하는데, 이는 미리 선언되거나 정의된 메서드가 아닌 compiler 에 의해 자동으로 추가되는 메서드이다.

    때문에 values() 메서드의 선언은 절대 찾을 수 없다. 다만 다음 예시처럼 직접 작동하는 것을 확인할 수는 있다.

    enum SomeEnum {
        Zero, One, Two, Three
    }
    
    for (Object obj : SomeEnum.values()) {
        System.out.println(obj + "\t" + obj.getClass());
    }
    Zero    class SomeEnum
    One     class SomeEnum
    Two     class SomeEnum
    Three   class SomeEnum

profile
나 같은게... 취준?!

0개의 댓글