✅ 컴파일 언어? 인터프리터 언어?
Compiler Language
- 소스 코드 전체를 한번에 기계어로 번역하여 실행 파일을 만듦
- 실행 속도 빠름
- 일부만 수정해도 다시 컴파일
Interpreter Language
- 한 줄씩 번역 및 실행 → 별도의 실행파일 생성 X
- 느린 실행 속도 (매번 코드 번역)
- 쉬운 수정, 테스트
Java Virtual Machine = 자바 프로그램을 실행하기 위한 가상 환경
- 컴파일러와 인터프리터의 장점을 결합
- 플랫폼 독립성 실현
- GC를 통해 더이상 사용되지 않는 메모리 자동 정리
- 자바 컴파일러 (Javac): .java를 .class(바이트코드)로 변환, 완전한 기계어가 아닌 중간 언어
- JVM 실행 → 인터프리터 방식으로 한줄씩 실행
- 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()
- Comparable interface implements하고 compareTo() 구현하여 Collections.sort()
- 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());