본문 바로가기

Computer Science/Java

JAVA vs C++

JAVA vs C++

JAVA vs C++

 

Java와 C++은 문법적으로 상당히 유사하며 같은 객체 지향 언어라는 점에서 공통점이 있습니다. 하지만, 차이점도 극명하게 존재합니다.

 

Java와 C++의 차이점

 

  1. 상속
    • C++은 다중 상속을 지원하지만 Java는 지원하지 않습니다. 다중 상속을 지원하는 언어에서는 다이아몬드 문제(Diamond Problem)이 발생하는데, C++에서는 다이아몬드 문제를 회피할 수 있는 기능을 제공합니다.
      • 다이아몬드 문제(Diamond Problem)
        • 다중 상속 시, 어느 클래스의 메소드를 상속받아야 하는지 모호한 문제로, 둘 이상의 부모에 같은 메소드가 정의되어 있을 경우, 어느 것을 상속받을지 모호하게 됩니다.
        • 인터페이스는 기능에 대한 선언만 해두면 되기 때문에, 다중 상속을 하더라도 충돌할 여지가 전혀 없습니다.
        • 하지만, Java 8 부터 default 메소드를 지원하기 때문에, 새로운 규칙을 제시하여 이에 대한 Solution을 제공합니다.
          • 첫 번째, 클래스나 슈퍼 클래스에서 정의한 메소드가 Default 메소드보다 우선권을 가집니다.
          • 두 번째, 위의 규칙 이외의 상황에서는 서브 인터페이스가 우선권을 가집니다.
          • 마지막으로, 그밖에는 명시적으로 Default 메소드를 Override하여 호출합니다.
    • C++은 friend 키워드를 지원하지만 Java는 지원하지 않습니다. 특정 클래스에 friend 키워드를 붙여서 클래스 혹은 메소드를 선언하면 이 키워드가 명명된 클래스나 메소드는 그 클래스의 private, protected로 선언된 영역에 접근할 수 있습니다. 하지만 이 방법은 객체 지향의 특징인 캡슐화를 무시하므로 객체의 은닉성을 파괴할 수 있기 때문에 특수한 경우가 아니면 사용을 지양합니다.
    • Java는 인터페이스를 지원하지만 C++은 그렇지 않습니다. 클래스의 다중 상속을 지원하지 않는 Java는 인터페이스를 통해 다중 상속을 구현해낼 수 있습니다. Java에서는 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있습니다. 인터페이스는 상수와 추상 메소드로만 구성되어 있으므로 여러 개의 인터페이스를 구현하더라도 다이아몬드 문제를 발생시키지 않습니다.
  2. 메모리 처리
    • Java는 객체를 메모리의 Heap 영역에만 할당할 수 있지만 C++은 Heap과 Stack 영역 모두에 할당이 가능합니다. C++에서는 new 키워드를 사용해 객체를 생성하면 Heap 영역에 객체가 할당되고 일반적인 변수 선언 방식으로 객체를 생성하면 Stack 영역에 할당됩니다. 하지만, Java에서는 일반적인 변수 선언 방식으로 객체를 생성할 수 없기 때문에 new 키워드를 이용해서 객체를 생성하게 되고 이때 객체는 Heap 영역에 할당됩니다.
    • Java는 메모리 해제가 자동으로 이루어지지만 C++은 프로그래머가 수동으로 메모리 해제를 해야합니다. Java에서는 Garbage Collector가 사용되지 않는 객체를 자동으로 해제해주지만, 프로그래머는 수동으로 GC를 조적할 수 없습니다. 반면, C++에서는 Destructor(소멸자)를 통해 직접 메모리 해제를 해주어야 합니다.
  3. 문법 및 기능
    • C++에서는 연산자 오버로딩을 지원하지만 Java는 지원하지 않습니다. 연산자 오버로딩은 단어 그대로 연산자를 재정의하여 활용하는 것인데, 객체 간 연산에 활용할 수 있습니다. 하지만 Java는 만들어질 때부터 연산자 오버로딩을 지원하지 않도록 개발되었다고 합니다.
    • Java는 익명 클래스(Anonymous Class)를 지원하지만 C++은 지원하지 않습니다. 익명 클래스는 Java에서 지원하는 기능인데 말 그대로 이름이 없는 클래스입니다. 인터페이스의 메소드 중 하나만 Override 하고 싶을 때 자주 사용되며, 클래스의 선언과 객체의 생성이 동시에 이루어지는 형태를 띄고 있습니다. Java는 익명 클래스를 통해 함수형 프로그래밍의 형태를 어느 정도 갖출 수 있습니다.
    • Java는 동적 바인딩(Dynamic Binding)을 택하고 있지만 C++은 정적 바인딩(Static Binding)을 택하고 있습니다. 하지만, C++은 virtual 키워드를 통해 동적 바인딩도 지원하기도 합니다.
      • 정적 바인딩
        • 컴파일 시, 어떤 함수를 호출할 지 결정하는 것입니다.
        • 실행 속도 측면에서 동적 바인딩보다 빠르지만, 융통성이 없습니다.
      • 동적 바인딩
        • 런타임 중, 실행 코드가 결정이 되는 것입니다.
        • 다형성으로 인해 융통성을 가질 수 있었지만, 실행 속도가 미세하게 느려집니다.
  4. 설계 목표
    • Java는 설계할 때, 보안과 빠른 이식성에 집중했지만, C++은 속도와 C언어와의 하위 호환성에 집중했습니다.
      • C++은 절차 지향 언어인 C의 효율성을 개선하기 위해 '객체 지향 프로그래밍'을 결합한 것이기 때문입니다.
  5. 컴파일과 런타임
    • Java는 가상 머신 바이트 코드로 컴파일하며, 이를 실행시키기 위해서는 가상 머신(JVM)이 필요합니다.
      • JVM은 VMware와 같은 본격적인 가상 머신이 아니라, 이론적인 가상 머신으로 사용자의 눈에는 보이지 않습니다.
      • Java는 JVM 위에서 간접적으로 실행되기 때문에 OS의 종류를 가리지 않습니다. 따라서 플랫폼 독립적이며 Windows에서 컴파일한 .class 파일을 Linux, Unix, Mac 등에서 수정하지 않고 실행시킬 수 있습니다.
    • C++은 각 운영체제(Windows, Linux, Mac)에 맞는 기계어로 컴파일합니다.

       

    → 이게 C++이 Java보다 실행 속도가 빠른 이유가 됩니다.
  6. 보안성
    • Java는 몇 가지 보안 메커니즘을 구현하여 잘못된 프로그램으로 인해 생기는 피해를 막아주도록 설계되어 있기 때문에 C++보다 보안성이 높습니다.

 

 

 

 

References

 

'Computer Science > Java' 카테고리의 다른 글

Call By Value vs Call By Reference  (0) 2021.04.08
추상 클래스와 인터페이스  (0) 2020.10.23
Java 메모리 - (3) Garbage Collector  (0) 2020.10.21
Java 메모리 - (2) JVM  (0) 2020.10.19
Java 메모리 - (1) Java 메모리 구조  (0) 2020.10.18