Java 기초
Java의 특징
운영체제에 독립적
JVM을 사용하는 구조 덕분에 같은 코드로 모든 운영체제에서 실행이 가능하다.
JVM (Java Virtual Machine)
개발자가 작성한 코드를 컴파일러가 JVM이 실행할 수 있는 bytecode로 변환해주면 JVM은 bytecode를 각 플랫폼에 맞는 기계어로 변환해준다.
객체 지향 언어 (Object-oriented language)
모든 기능을 객체로 만들어 사용한다.
함수형 프로그래밍 지원
Java 8 버전부터 람다식, 스트림을 지원한다.
Garbage collection
메모리의 생성과 소멸을 개발자가 따로 설계하지 않고 garbage collector가 사용하지 않는 메모리를 수거한다.
변수와 타입 (Variable and type)
기본형과 참조형
기본형
boolean- 정수형
byte,short,char,int,long - 실수형
float,double
참조형
String, 배열, enum, 인터페이스, 클래스 등 다른 모든 데이터 타입
기본형과 참조형의 차이
변수를 지정하고 대입했을 때 변수가 어떻게 값을 저장하는가에 따라 나뉜다.
기본형의 경우 변수에 담을 때 값 그 자체를 저장하게 되고 참조형의 경우 변수에 담을 때 값이 저장된 메모리의 힙 영역을 가리키는 주소를 저장하게 된다.
References
- Chapter 4. Types, Values, and Variables
- What's the difference between primitive and reference types?
Endianness
메모리에 값을 저장할 때 각 바이트를 배열하는 순서를 endianness라고 한다.
Big-endian은 더 큰 값을 표현하는 바이트가 더 앞에 오고 little-endian은 더 작은 값은 표현하는 바이트가 앞으로 온다.
Endianness가 다른 플랫폼들이 있기 때문에 변환이 필요한지 잘 확인해야 한다.
2's complement
정수형 타입에서 음수를 표현할 때 2's complement를 이용한다.
2's complement는 각 비트를 반전시키고 거기에 1을 더함으로써 구할 수 있다.
2's complement로 음수를 표현하는 경우 덧셈과 뺄셈이 자연스럽게 가능하다.
Further Reading
부동소수점 연산 (Floating-point arithmetic)
정수형의 범위를 넘어가는 숫자를 표현할 때 부동소수점을 사용한다.
Character
char 타입을 다루는 여러 static 메소드를 담은 클래스이다.
getNumericValue
public static int getNumericValue(char ch)
ch 매개변수가 담은 문자가 숫자일 때 그 숫자를 int 타입으로 반환해준다.
forDigit
public static char forDigit(int digit, int radix)
digit 매개변수가 담은 그 숫자에 해당하는 char로 반환해준다.
radix 매개변수로 몇 진법으로 표현할지 결정한다.
Double.parseDouble
public static double parseDouble(String s) throws NumberFormatException
문자열 s가 double 타입으로 표현 가능한 문자열이면 double 타입으로 반환해준다.
문자열 (String)
String
기본 문자열 클래스다.
인스턴스가 한 번 생성되면 그 값을 읽기만 가능하고 변경할 수 없다.
StringBuffer
String 클래스와 다르게 인스턴스가 생성된 이후 그 값을 변경, 추가할 수 있다.
Thread-safe하다.
StringBuilder
여러 개의 문자열을 더할 때 중간 결과에 해당하는 String 인스턴스를 만들지 않기 위해 사용한다.
간단한 문자열 연결의 경우 컴파일러에서 알아서 '+' 연산을 StringBuilder로 최적화해준다.
반복문으로 '+' 연산을 하는 경우만 StringBuilder를 사용해도 무방하다.
StringBuffer와 호환되는 API를 지원하지만 동기화를 보장하지 않기 때문에 싱글스레드 환경에서 사용해야 한다.
StringBuffer보다 빠르기때문에 멀티스레드 환경이 아니라면 StringBuilder를 사용하는 것이 좋다.
References
StringTokenizer
문자열을 구분자로 나누어 토큰으로 만들어준다.
기본 구분자는 공백이다.
공식 문서에 따르면, 호환성을 위해 유지되는 legacy class이기 때문에 새로운 코드를 작성할 때는 String.split이나 java.util.regex 패키지를 사용하는 것이 권장된다.
Further Reading
- Formatter (Java SE 11 & JDK 11 )
- Is it better practice to use String.format over string Concatenation in Java?
연산자 (Operator)
연산자 우선순위
다음 표에서 위에 있는 연산자부터 실행된다.

References
>> vs. >>>
>>는 오른쪽으로 shift하는데 제일 왼쪽에 추가되는 비트가 부호에 따라 달라지고 >>>는 sign에 상관 없이 0이 추가된다.
References
콘솔 입출력 (I/O)
Scanner
System.in 또는 파일 등에 담긴 텍스트를 읽을 때 사용한다.
정규표현식을 활용하여 토큰화도 가능하다.
조건문
switch expressions
JDK 14부터 switch가 statement가 아닌 expression으로도 사용 가능하다.
추가로 :가 아닌 ->로 case문을 구성할 수 있다
// ":" 사용
switch (num) {
case 1:
str = 1 + "st";
break;
...
}
// "->" 사용
switch (num) {
case 1 -> str = "one";
// ","로 여러 case를 묶어서 표현할 수 있다.
case 2, 3, 4, 5 -> str = "bigger than one";
...
}
// switch expression
str = switch (num) {
case 1 -> "one";
...
// expression이므로 값이 무조건 존재해야 해서 default가 필수다.
default -> "";
}
// switch expression에서 ":" 사용시 yield문으로 값을 생산해야한다.
str = switch (num) {
case 1:
yield "one";
...
default:
yield "";
}
->를 사용하면 break나 yield를 쓰지 않아도 되고 여러 개의 case문을 묶어서 표현할 수 있어서 편리하다.
물론 expression으로 사용할 때 -> 이후 여러 줄의 코드를 블록으로 나타내는 경우 블록 내에서 yield문을 사용해야 한다.
References
- The if-then and if-then-else Statements
- The switch Statement
- 14.9. The
ifStatement - 14.11. The
switchStatement
반복문
Enhanced for
배열이나 컬렉션을 iteration하기 위한 특수한 for문의 형태이다.
가능한 경우라면 이 형태를 활용하는 것이 권장된다.
class EnhancedForDemo {
public static void main(String[] args){
int[] numbers =
{1,2,3,4,5,6,7,8,9,10};
for (int item : numbers) {
System.out.println("Count is: " + item);
}
}
}
References
배열 (Array)
Arrays.copyOf
public static <T> T[] copyOf(T[] original, int newLength)
배열을 시작부터 newLength만큼 복사해준다.
newLength가 original.length보다 작으면 그만큼 잘라내고, original.length보다 크면 그만큼 해당 타입의 초기값으로 채워준다.
Arrays.copyOfRange
public static <T> T[] copyOfRange(T[] original, int from, int to)
배열을 배열 내의 from index와 to index로 범위를 정하여 복사해준다.
to index의 직전에 있는 원소까지 복사되는 것에 유의해야 한다.
배열의 끝까지 복사하려고 하면 to값은 original.length가 된다.
System.arraycopy
public static void arraycopy(
Object src, int srcPos, Object dest, int destPos, int length)
src의 srcPos index부터 length만큼의 값을 복사하여 dest에 destPos index부터 넣어준다.