이 문서는 Java SE의 주요 특징을 중심으로 C++와의 비교를 통해 핵심 내용을 설명합니다.
Java의 기본 데이터형
| 데이터형 이름 | 차원 | 默시 값 | 페기지 클래스 |
|---|---|---|---|
| byte | 1 | 0 | Byte |
| short | 2 | 0 | Short |
| char | 2 | '\u0000' | Character |
| int | 4 | 0 | Integer |
| long | 8 | 0L | Long |
| float | 4 | 0.0f | Float |
| double | 8 | 0.0d | Double |
| boolean | 1비트 | false | Boolean |
C++와 달리 Java는 함수 매개변수의默시 값을 지정할 수 없습니다. 이 경우 함수 오버로드를 통해 해당 기능을 구현할 수 있습니다:
public class Test {
public int func(int a, String b){
// 구현 내용
}
public int func(){
return func(0, new String("기본값"));
}
}
Java의 형 변환은 모두 동적입니다. 이는 C++의 dynamic_cast와 유사합니다. 위험한 형 변환 시 예외가 발생합니다.
Java의 char는 기본적으로 2바이트를 차지하며默시 인코딩 방식은 UTF-16입니다.
Java의 abstract 키워드는 함수를修饰할 때는 C++의 virtual 키워드와 유사하며, 클래스를修饰할 때는 C++의 추상 클래스와 유사합니다. 추상 클래스는 일반 함수도 포함할 수 있습니다. 추상 클래스를 가지는 클래스는 반드시 abstract 키워드로修饰해야 합니다.
Java의 final 키워드는 함수와 클래스를修饰할 때 C++의 final과 같은 효과를냅니다. 또한 변수를修饰할 수 있으며, 이는 C++의 const와 유사합니다.
Java의 interface는 C++의 추상 클래스와 유사하지만, 다중 상속을 지원합니다. 하나의 클래스는 여러개의 interface를 implements할 수 있지만, Java는 다중 기반 클래스를 지원하지 않습니다. interface는 멤버를 가질 수 있으며, 이들은 public static final로修饰되어야 합니다. interface의 메서드는 모두 추상 메서드이거나 default로修饰된 메서드일 수 있습니다.
Java의 상속과 interface 구현의 차이: 상속은 "종류"의 관계이며, 구현은 "소유"의 관계입니다. 예를 들어 '천鹅' 클래스는 '鸟' 클래스를 상속하고, '날개' interface를 구현할 수 있습니다.
Java는 연산자 오버로딩을 지원하지 않습니다. 연산자 대신 메서드를 사용해야 합니다. 예를 들어 두개의 String 객체를 비교할 때는 equals() 메서드를 사용해야 합니다.
Java는 삼항 연산자 내에서 할당문을 사용할 수 없습니다. 예를 들어 return (f[x] == x) ? x : f[x] = find(f[x]);은 컴파일 에러를 일으킵니다. 이때는 return (f[x] == x) ? x : (f[x] = find(f[x]));와 같이 괄호를 추가해야 합니다.
Java의 객체 복사 방법
- 객체 복사 방법
- 객체의 clone() 메서드 재정의
- 직렬화와 역직렬화를 통한 복사
protected Son deepClone() throws IOException, ClassNotFoundException {
Son son = null;
ByteArrayOutputStream byOut = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byOut);
outputStream.writeObject(this);
ByteArrayInputStream byIn = new ByteArrayInputStream(byOut.toByteArray());
ObjectInputStream inputStream = new ObjectInputStream(byIn);
son = (Son) inputStream.readObject();
return son;
}
org.apache.commons라이브러리의 유틸리티 클래스를 사용
Java의 모든 객체는 Object 클래스를 상속합니다. 이 클래스에는 재정의할 수 있는 편의 메서드들이 있습니다:
- toString(): 객체를 문자열로 표현
- hashCode(): 객체의 해시값을 반환
- equals(): 객체의 동등성 여부를 판단
Object의 주요 메서드:
- getClass(): 객체의 런타임 클래스를 반환
- wait(), notify(): 멀티스레드 환경에서 사용
- clone(): 객체를 복사
Java의 참조 유형은 다음과 같이 분류됩니다:
- 강한 참조: 일반적인 참조, GC가 실행될 때까지 유지
- 부드러운 참조: 메모리 부족 시 GC에 의해 해제
- 약한 참조: GC가 실행될 때마다 해제
- 가상 참조: 주로 픽셀 버퍼 등과 함께 사용
Java의 내부 클래스란 외부 클래스 내부에서 선언된 클래스를 말합니다:
public class OuterClass {
class InnerClass {
}
static class StaticInnerClass {
}
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();
StaticInnerClass staticInnerClass = new StaticInnerClass();
}
}
Java의 Arrays.sort() 메서드는 다음과 같이 작동합니다:
- 기본형 배열: Dual-Pivot Quick Sort
- 객체형 배열: TimSort (병합 및 이진 산입 알고리즘)
Java NIO는 비동기 IO를 제공하며, Channel, Buffer, Selector로 구성됩니다. 기존 IO와의 주요 차이점은 버퍼 기반 작업으로 비지연 처리가 가능하다는 점입니다.
Java의 기본형 데이터형은 모두 패키지형 클래스와一一对应합니다. 기본형과 패키지형 간의 상호운용성은 컴파일러가 자동으로 처리합니다:
- 할당 연산
- 산술 연산
- 비교 연산
- equals() 호출
- 컬렉션 추가
패키지형 클래스의 캐시 영역:
- Byte, Short, Integer, Long: -128 ~ 127 범위 내 캐시
- Character: 0 ~ 127 범위 내 캐시
String의 특징:
- 내부는 최종적으로 변경할 수 없는 배열 (JDK 9 이전: char배열, JDK 9 이후: byte배열)
- 불변성으로 인해 스레드セ이프
- StringBuilder: 불변성 없는 String 대용, 스레드안전X
- StringBuffer: 스레드セ이프 버전의 StringBuilder
다중 인터페이스 구현 규칙:
- 클래스 우선 적용
- 인터페이스 간의 충돌 해결은 명시적 오버라이드를 통해
JDK 8의 주요 신기능:
- interface의 default 메서드
- method reference (람다 표현식의 단축)
- Optional 클래스
- Stream API
추후 더 많은 내용을 추가 예정입니다...