본문 바로가기

Java

[JAVA] 자바를 쓰면서 소소하게 헷갈렸던 것들 모음

컴파일 언어? 인터프리터 언어?

Compiler Language

  • 소스 코드 전체를 한번에 기계어로 번역하여 실행 파일을 만듦
  • 실행 속도 빠름
  • 일부만 수정해도 다시 컴파일

Interpreter Language

  • 한 줄씩 번역 및 실행 → 별도의 실행파일 생성 X
  • 느린 실행 속도 (매번 코드 번역)
  • 쉬운 수정, 테스트

Java Virtual Machine = 자바 프로그램을 실행하기 위한 가상 환경

  • 컴파일러와 인터프리터의 장점을 결합
  • 플랫폼 독립성 실현
  • GC를 통해 더이상 사용되지 않는 메모리 자동 정리
  1. 자바 컴파일러 (Javac): .java를 .class(바이트코드)로 변환, 완전한 기계어가 아닌 중간 언어
  2. JVM 실행 → 인터프리터 방식으로 한줄씩 실행
  3. JIT(Just in Time Compiler): 인터프리터의 속도 단점을 보완하기 위해 JIT 컴파일러 사용
    • 자주 사용되는 코드를 실시간으로 기계어로 번역하여 캐시에 저장
    • 다음부터는 번역 없이 실행하여 성능을 향상

⇒ 소스코드를 바이트 코드로 미리 컴파일하고 실행 시점에서는 JVM이 인터프리팅과 JIT 컴파일을 함께 사용하는 하이브리드 방식

 

자바 메모리 구조

  • Class
    • 클래스 정보, static, method 등
    • main 또한 class에 저장
    • constant pool도 여기
  • Stack
    • main이 실행될 때 stack이 불러와짐
    • 변수가 이쪽에 저장됨
  • Heap
    • new로 변수를 초기화 했을 때 그 값이 이쪽으로 저장
    • 배열 값 같은 것도 heap에 저장

 

String

String s1 = "Hello"
String s2 = "Hello"
String s3 = new String("Hello");
  • "Hello"는 상수이므로 constant pool에 저장됨 → s1은 immutatble
  • s2는 "Hello"라는 상수를 참조하고 있음 → s1 == s2
  • BUT s3은 새로운 객체로 저장하고 있음, 따라서 값을 비교하고 싶을 때는 equals()를 사용해야 한다

 

Object Class Method

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

public boolean equals(Object obj) {
    return (this == obj);
}

public native int hashCode();

⇒ 자바의 모든 class는 Object를 암묵적으로 상속하고 있기 때문에 toString()을 override해서 사용하는 것

 

Modifier

Access Modifier : public > protected > (default) > private

Usage Modifier

  • static
    • static block에서는 class가 메모리에 로드된 후 호출
    • instance block에서는 객체 생성 시마다 호출
    • static method는 스택에서 잡히기 때문에 나중에 날라감
  • `final``
    • final class는 상속 불가
    • final method는 override 불가
    • final variable = 상수
      • blank final variable의 경우 변수를 final로 정의하고 생성자에서 값을 할당할 수 있다 ∽ 플러터의 const

 

abstract VS interface

구분 abstract interface
목적 'is a' 관계 'can do' 관계
상속 extends & 단일 상속 implements & 다중 구현
변수 일반 변수, 상수 모두 선언 가능 public static final만 선언 가능
메서드 추상 메소드와 일반 메소드 모두 가능 public abstract (Java 8부터 default, static 가능)
생성자 가질 수 있음 가질 수 없음

 

Overriding VS Overloading

구분 Overriding Overloading
기반 상속, super로부터 상속받은 기능 중 특정 기능을 재정의 하나의 클래스나 상속받은 클래스 내 같은 이름으로 메소드를 정의
방식 return type, method 타입, 파라미터 list는 항상 동일 method 이름은 같고 파라미터 list는 다르게

 

Collections.sort()

  1. Comparable interface implements하고 compareTo() 구현하여 Collections.sort()
  2. Comparator interface에 있는 compare()를 구현한 구현체를 생성하여 Collection.sort()호출하면서 구현체 전달
    // 구현체 전달
    class MyComparator implements Comparator<Person> {
     @Override
     public int compare(Person o1, Person o2) {
         return o1.getAge() - o2.getAge();
     }
    }
    
    Collections.sort(list, new MyComparator());
    
    // 익명 클래스 사용
    Collections.sort(list, new Comparator() {
      @Override
      public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
      }
    });
    
    // 람다식 사용 1
    Collections.sort(list, (Person o1, Person o2) -> {
      return o1.getAge() - o2.getAge();
    });
    // 람다식 사용 2
    Collections.sort(list, (Person o1, Person o2) -> o1.getAge() - o2.getAge());