Kotlin을 배우다가, 결국 Java도 정리할 수밖에 없게 되었다.
기본 타입들, 구문
- 모든 코드조각이 클래스 안에 포함되어야 한다.
- 전역 변수는 없고, static은 쓸 수 있다.
- 변수, 함수는 카멜 표기법, 클래스는 파스칼 표기법
- primitive 타입들: Primitive는 그 자체로 값임
- 정수:
byte
,char
,short
,int
,long
- 실수:
float
,double
- 논리:
boolean
- 정수:
- Wrapper class를 제공해줌
- 예를들어
Integer
- 이 클래스들은 오브젝트이며, Reference로 지칭됨
- Generic에 넣어줄때 이용됨 (Generic은 Primitive를 못받음)
- 예를들어
String
은 라이브러리로 제공- 연산자는 거의 C랑 똑같음
- JVM은 Generation GC 함
- 배열은 C++ vector에 가까움
- Bound 체크를 해줌
- 한번 만들면 append 불가능.
- 이중일때 서로 다른 사이즈 할당이 가능
{ {1} , {1,2} }
- Vector 같은것이 필요할 때 ArrayList를 쓸 것.
- 조건문, 반복문은 C++과 완전 같다.
클래스, 상속
- 클래스 선언 및 프로퍼티 Visibility 제한자들은 C++과 동일
- 최상위 클래스에는
public
만 붙일 수 있음 - 내부 클래스에는 3개 모두 가능
- 멤버 메소드의 오버로딩 가능.
- 연산자 오버로딩 안됨
- 상속은 extends로 받음, 오버라이딩 가능
@Override
를 붙여서 실수 방지super()
로 부모 클래스의 생성자 이용 가능- 단
super
가 가장 먼저 불려야함.
- 단
super
로 사용하는 경우는 부모 객체의 Instance 접근 가능.
this
, 생성자 사용 가능. C++과 거의 같음
익명 클래스
- 일회성으로 선언해서 사용 가능한 익명 클래스(재사용 불가)
new ArrayList() { /* members */}
의 형태로 사용- final 혹은 effective final을 만족하는 외부변수만 참조 가능.
인터페이스
interface
로 인터페이스 선언- 추상 메서드 + 상수 +
default
메서드 +static
메서드 implements
로 클래스에서 사용- 하나의 클래스는 여러개의 인터페이스를 구현할 수 있음.
default
메서드로 구현을 집어넣을 수 있음default
에서는 상수, 다른default
메서드,static
메서드 사용 가능- 상속이 가능하며, 다중상속시 오버라이딩 필수
static
메서드도 구현을 집어넣을수 있으나 상속되지 않음
한정자, 제어자
final
- final 변수: 상수 취급
- final 메소드: 오버라이드 불가
- final 클래스: 상속 불가
abstract
로 추상클래스 선언- 추상 메서드만 포함 가능
- 접근 제어자
public
,private
,protected
예외
try
,catch
,finally
을 씀Throwable
을 상속받은 객체만 던질 수 있음.- 던지는 클래스에서는
throws
로 던져지는 예외들을 명시해주어야함
제너릭
기초
- 제너릭: Parameterized type
- Generic으로 쓸 수 없는 타입들
- Anonymous inner classes
- Exception types
- Enum types
- 용법
- Generic Class/Interface: 클래스 이름 뒤에 Generic을 선언
- Generic Method: 함수 이름 앞에 Generic을 선언
- 기본적으로 Syntactic Sugar임.
- Generic을 지우고, 해당 위치를 Object로 바꿔도 아무 문제 없이 사용가능
- 명시적 형변환은 필요할 수 있음
- 런타입에는 제너릭 타입 정보를 지움
- 모든 Generic instance는 static을 공유
- 타입을 활용한 분기 불가능
- 타입을 쓰고싶으면 class 오브젝트를 활용하거나 해야함
- Generic을 지우고, 해당 위치를 Object로 바꿔도 아무 문제 없이 사용가능
Generic 타입 선언/사용
- Type 선언시 바운드 가능
- Unbounded type parameter:
<T>
- Bounded type parameter:
<T extends Numbers>
- Recursive type bound
<T extends List<T>>
- Unbounded type parameter:
- 타입 사용시 wildcard type 사용 가능
- Unbounded wildcard
Pair<?,?> limit
- Bounded wildcard
Iterable<? extends E> limit
Iterable<? super E> limit
- Unbounded wildcard
- 선언시 생략 가능
Box box<Integer> = new Box<>();
- Generic 타입으로 캐스팅 할 경우 Raw 타입으로 캐스팅되어버림
- 아래 예에서는
o
가ArrayList<String>
이 아닌ArrayList
로 캐스팅1
2
3
4
5ArrayList<Integer> a = new ArrayList<Integer>(); a.add(1); Object o = a; ArrayList<String> b = (ArrayList<String>) o; // No error, unchecked System.out.println(b.get(0)); // Error! Hard to find.
- 아래 예에서는
List<Object>
는List<String>
의 서브타입이 아님- 제너릭들은 서브타입 관계를 가지지 않음.
void printAll(ArrayList<Object> c)
에ArrayList<String>
대입불가.void printAll(ArrayList<? extends Object> c)
에는 대입 가능
- Array와 섞어서 쓰면 거진 다 Type Unsafe임.
- 거의 섞어서 쓸일이 없음 그냥 Collections를 쓰자.
try-with-resources
try
와 소괄호를 이용해 자원을 자동해제 할 수 있다. Python의 with처럼 쓸 수 있음.1
2
3
4
5
6try ( FileReader fr = new FileReader("data.txt"); BufferedReader br = new BufferedReader() ) { return br.readLine(); }