변수와 기본 타입 문서의 구현 코드다.
// 실행: docker run --rm -v "$PWD":/w -w /w eclipse-temurin:21-jdk java 02_java-primitive-types_impl.java
// 변수와 기본 타입 문서의 표(크기·범위), printf 서식, Scanner 입력을 확인한다.
import java.util.Scanner;
class PrimitiveTypesImpl {
static void check(boolean ok, String what) {
if (!ok) throw new AssertionError(what);
}
public static void main(String[] args) {
// 1. 정수 타입의 크기(비트)와 범위
check(Byte.SIZE == 8 && Byte.MIN_VALUE == -128 && Byte.MAX_VALUE == 127, "byte");
check(Short.SIZE == 16 && Short.MIN_VALUE == -32768 && Short.MAX_VALUE == 32767, "short");
check(Character.SIZE == 16 && (int) Character.MIN_VALUE == 0 && (int) Character.MAX_VALUE == 65535, "char");
check(Integer.SIZE == 32 && Integer.MIN_VALUE == -2147483648 && Integer.MAX_VALUE == 2147483647, "int");
check(Long.SIZE == 64 && Long.MIN_VALUE == -9223372036854775808L
&& Long.MAX_VALUE == 9223372036854775807L, "long");
check(Float.SIZE == 32 && Double.SIZE == 64, "float 32비트, double 64비트");
// 범위는 -2^(n-1) ~ 2^(n-1) - 1
check(Byte.MIN_VALUE == -(1 << 7) && Byte.MAX_VALUE == (1 << 7) - 1, "byte 범위 공식");
check(Integer.MAX_VALUE == (int) ((1L << 31) - 1), "int 범위 공식");
// 2. char는 글자의 번호(유니코드)를 담는 정수다
char c = 'A';
check(c == 65, "'A'는 65");
char han = '가';
check((int) han == 44032, "'가'는 44032");
// 3. boolean
int x = 10;
check((x == 20) == false, "x==20");
check((x != 20) == true, "x!=20");
check((x > 20) == false, "x>20");
check((0 < x && x < 20) == true, "0<x && x<20");
check((x < 0 || x > 200) == false, "x<0 || x>200");
// 4. 리터럴: 정수는 int, 소수는 double로 본다
long big = 3000000000L; // L이 없으면 컴파일 오류
float f = 170.5f; // f가 없으면 컴파일 오류
check(big == 3_000_000_000L, "long 리터럴");
check(f == 170.5f, "float 리터럴");
// 5. 변수의 범위: 블록 안에서 만든 변수는 블록 밖에서 쓸 수 없다(쓰면 컴파일 오류)
int var1 = 1;
int seen = 0;
if (var1 == 1) {
int var2 = 2;
seen = var1 + var2; // var1, var2 모두 쓸 수 있다
}
for (int i = 0; i < 1; i++) {
int var3 = 3;
seen += var1 + var3; // var1, var3 쓸 수 있다. var2는 못 쓴다
}
check(seen == 7, "범위 예제의 합 7");
// 6. printf 서식 (문서의 서식 표). 빈칸을 _로 바꿔 비교한다
check(String.format("%d", 123).equals("123"), "%d");
check(String.format("%6d", 123).replace(' ', '_').equals("___123"), "%6d");
check(String.format("%-6d", 123).replace(' ', '_').equals("123___"), "%-6d");
check(String.format("%06d", 123).equals("000123"), "%06d");
check(String.format("%10.2f", 123.45).replace(' ', '_').equals("____123.45"), "%10.2f");
check(String.format("%-10.2f", 123.45).replace(' ', '_').equals("123.45____"), "%-10.2f");
check(String.format("%010.2f", 123.45).equals("0000123.45"), "%010.2f");
check(String.format("%s", "abc").equals("abc"), "%s");
check(String.format("%6s", "abc").replace(' ', '_').equals("___abc"), "%6s");
check(String.format("%-6s", "abc").replace(' ', '_').equals("abc___"), "%-6s");
check(String.format("%%").equals("%"), "%%");
check(String.format("나는 %s에 살고 있다.", "동작구").equals("나는 동작구에 살고 있다."), "%s 문장");
check(String.format("나는 %d살이다.", 20).equals("나는 20살이다."), "%d 문장");
// 카드 C2
check(String.format("[%5d|%-5s|%.1f]", 42, "ab", 3.14159).equals("[ 42|ab |3.1]"), "카드 C2");
// 7. Scanner: 키보드 대신 문자열을 입력으로 준다. nextLine은 엔터 앞까지 한 줄을 읽는다
Scanner scanner = new Scanner("홍길동\n20\n");
String name = scanner.nextLine();
String ageText = scanner.nextLine();
scanner.close();
check(name.equals("홍길동"), "첫 줄");
check(ageText.equals("20"), "둘째 줄은 글자 \"20\"이다");
check(Integer.parseInt(ageText) + 1 == 21, "숫자로 바꿔야 계산할 수 있다");
System.out.println("ALL CHECKS PASSED");
}
}