객체는 필드에 상태를 저장한다는 것을 이미 배웠습니다. 하지만 Java 프로그래밍 언어에서는 _변수_라는 용어도 사용합니다. 이 섹션에서는 이 관계와 변수 명명 규칙 및 규칙, 기본 데이터 타입(기본 유형, 문자열 및 배열), 기본값 및 리터럴에 대해 설명합니다.

 

원시 유형

Java 프로그래밍 언어는 정적 형식이므로 모든 변수를 사용하기 전에 먼저 선언해야 합니다. 여기에는 이미 보신 것처럼 변수의 유형과 이름을 명시하는 것이 포함됩니다:

int gear = 1;

이렇게 하면 프로그램에 gear라는 필드가 존재하고 숫자 데이터를 보유하며 초기값이 1임을 알립니다. 변수의 데이터 타입에 따라 포함할 수 있는 값과 변수에 대해 수행할 수 있는 연산이 결정됩니다. Java 프로그래밍 언어는 int 외에도 7개의 다른 기본 데이터 타입을 지원합니다. 기본 타입은 언어에 의해 미리 정의되며 예약된 키워드로 이름이 지정됩니다. 프리미티브 값은 다른 프리미티브 값과 상태를 공유하지 않습니다. Java 프로그래밍 언어에서 지원하는 8가지 기본 데이터 타입은 다음과 같습니다:

  • byte: byte 데이터 타입은 8비트 부호 2의 보수 정수입니다. 최소값은 -128이고 최대값은 127(포함)입니다. byte 데이터 타입은 메모리 절약이 실제로 중요한 대규모 배열에서 메모리를 절약하는 데 유용할 수 있습니다. 또한 변수의 범위가 제한되어 있어 코드를 명확히 하는 데 도움이 되는 경우 int 대신 사용할 수 있으며, 변수의 범위가 제한되어 있다는 사실은 일종의 문서화 역할을 할 수 있습니다.

  • short: short 데이터 타입은 16비트 부호 2의 보수 정수입니다. 최소값은 -32,768이고 최대값은 32,767(포함)입니다. byte와 마찬가지로 동일한 지침이 적용되므로 메모리 절약이 실제로 중요한 상황에서 큰 배열의 메모리를 절약하기 위해 쇼트를 사용할 수 있습니다.

  • int: 기본적으로 int 데이터 타입은 최소값이 -231이고 최대값이 231-1인 32비트 부호화된 2의 보수 정수입니다. Java SE 8 이상에서는 int 데이터 타입을 사용하여 최소값이 0이고 최대값이 232-1인 부호 없는 32비트 정수를 나타낼 수 있습니다. 부호 없는 정수로 int 데이터 타입을 사용하려면 Integer 클래스를 사용합니다. 자세한 내용은 숫자 섹션을 참조하세요. 부호 없는 정수에 대한 산술 연산을 지원하기 위해 compareUnsigned()와 같은 정적 메서드가 Integer 클래스에 추가되었습니다.

  • long: long 데이터 타입은 64비트 2의 보수 정수입니다. 부호화된 long의 최소값은 -263이고 최대값은 263-1입니다. Java SE 8 이상에서는 long 데이터 타입을 사용하여 최소값이 0이고 최대값이 264-1인 부호 없는 64비트 긴 값을 나타낼 수 있습니다. int가 제공하는 값보다 더 넓은 범위의 값이 필요한 경우 이 데이터 타입을 사용합니다. Long 클래스에는 부호 없는 길이에 대한 산술 연산을 지원하는 compareUnsigned(), [divideUnsigned()](https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Long.html#divideUnsigned(int,int) 등과 같은 메서드도 포함되어 있습니다.

  • float: float 데이터 타입은 단정밀도(single-precision) 32비트 IEEE 754 부동 소수점입니다. 이 값의 범위는 이 설명의 범위를 벗어나지만, Java 언어 사양부동 소수점 유형, 형식 및 값 섹션에 명시되어 있습니다. byteshort에 대한 권장 사항과 마찬가지로, 부동 소수점 숫자의 큰 배열에 메모리를 저장해야 하는 경우 double 대신 float를 사용하세요. 이 데이터 타입은 통화와 같은 정확한 값에는 절대 사용해서는 안 됩니다. 이 경우 대신 java.math.BigDecimal 클래스를 사용해야 합니다. 숫자 및 문자열에서는 BigDecimal 및 Java 플랫폼에서 제공하는 기타 유용한 클래스를 다룹니다.

  • double: double 데이터 타입은 배정밀도(double-precision) 64비트 IEEE 754 부동 소수점입니다. 이 값의 범위는 이 설명의 범위를 벗어나지만, Java 언어 사양부동 소수점 유형, 형식 및 값 섹션에 명시되어 있습니다. 십진수 값의 경우 일반적으로 이 데이터 타입이 기본값으로 선택됩니다. 위에서 언급했듯이 이 데이터 타입은 통화와 같은 정밀한 값에는 절대 사용해서는 안 됩니다.ㅋ

  • boolean: boolean 데이터 타입에는 가능한 값이 두 가지뿐입니다: truefalse 두 가지 값만 가능합니다. 이 데이터 타입은 참/거짓 조건을 추적하는 간단한 플래그에 사용합니다. 이 데이터 타입은 한 비트의 정보를 나타내지만, 그 “size”는 정확하게 정의되어 있지 않습니다.

  • char: char 데이터 타입은 단일 16비트 유니코드 문자입니다. 최소값은 \u0000(또는 0)이고 최대값은 \uffff(또는 65,535 포함)입니다.

위에 나열된 8가지 기본 데이터 타입 외에도 Java 프로그래밍 언어는 java.lang.String 클래스를 통해 문자 문자열에 대한 특별한 지원도 제공합니다. 예를 들어 문자열을 큰따옴표로 묶으면 자동으로 새 String 객체가 생성됩니다:

String s = "this is a string";

String 객체는 불변이므로 일단 생성되면 그 값을 변경할 수 없습니다. String 클래스는 엄밀히 말해 원시 데이터 타입은 아니지만, 언어에서 제공하는 특별한 지원을 고려하면 그렇게 생각하는 경향이 있을 것입니다. 문자열 섹션에서 String 클래스에 대해 자세히 알아볼 수 있습니다.

 

기본값으로 변수 초기화하기

필드가 선언될 때 항상 값을 할당할 필요는 없습니다. 선언되었지만 초기화되지 않은 필드는 컴파일러에 의해 합리적인 기본값으로 설정됩니다. 일반적으로 이 기본값은 데이터 타입에 따라 0 또는 null이 됩니다. 그러나 이러한 기본값에 의존하는 것은 일반적으로 잘못된 프로그래밍 스타일로 간주됩니다.

다음 표에는 위의 데이터 타입에 대한 기본값이 요약되어 있습니다.

Data TypeDefault Value (for fields)
byte0
short0
int0
long0L
float0.0f
double0.0d
char\u0000
String (or any object)null
booleanfalse

지역 변수는 약간 다릅니다. 컴파일러는 초기화되지 않은 지역 변수에 기본값을 할당하지 않습니다. 지역 변수가 선언된 곳에서 초기화할 수 없는 경우, 사용하기 전에 값을 할당해야 합니다. 초기화되지 않은 로컬 변수에 액세스하면 컴파일 타임 오류가 발생합니다.

 

리터럴로 값 만들기

원시 타입의 변수를 초기화할 때 new 키워드를 사용하지 않는다는 것을 눈치채셨을 것입니다. 원시 타입은 언어에 내장된 특수 데이터 타입으로, 클래스에서 생성된 객체가 아닙니다. 리터럴은 고정 값의 소스 코드 표현으로, 계산할 필요 없이 코드에서 직접 리터럴을 표현할 수 있습니다. 아래 그림과 같이 기본 유형의 변수에 리터럴을 할당할 수 있습니다:

boolean result = true;
char capitalC = 'C';
byte b = 100;
short s = 10000;
int i = 100000;

 

정수 리터럴

정수 리터럴은 문자 L 또는 l로 끝나면 long 유형이고, 그렇지 않으면 int 유형입니다. 소문자 l은 숫자 1과 구별하기 어렵기 때문에 대문자 L을 사용하는 것이 좋습니다.

정수형인 byte, short, int, long의 값은 int 리터럴에서 생성할 수 있습니다. int 범위를 초과하는 long 타입의 값은 long 리터럴에서 생성할 수 있습니다. 정수 리터럴은 다음 숫자 체계로 표현할 수 있습니다:

  • 10진수: 0부터 9까지의 숫자로 구성된 10진수로, 일상적으로 사용하는 숫자 체계입니다.
  • 16진수: 숫자 0부터 9까지와 문자 A부터 F까지로 구성된 16진수입니다.
  • 2진수: 2진수: 숫자 0과 1로 구성된 2진수(Java SE 7 이상에서 이진 리터럴을 생성할 수 있음)

범용 프로그래밍의 경우 십진수 체계가 유일한 숫자 체계일 가능성이 높습니다. 그러나 다른 숫자 시스템을 사용해야 하는 경우 다음 예제에서 올바른 구문을 확인할 수 있습니다. 접두사 0x는 16진수를 나타내고 0b는 2진수를 나타냅니다:

// The number 26, in decimal
int decimalValue = 26;
 
//  The number 26, in hexadecimal
int hexadecimalValue = 0x1a;
 
// The number 26, in binary
int binaryValue = 0b11010;

 

부동 소수점 리터럴

부동 소수점 리터럴은 문자 F 또는 f로 끝나는 경우 플로트 유형이고, 그렇지 않으면 더블 유형이며 선택적으로 문자 D 또는 d로 끝날 수 있습니다.

부동 소수점 유형(floatdouble)은 E 또는 e( 과학적 표기법), F 또는 f(32-bit float literal) 및 D 또는 d(64-bit double literal; 기본값이며 관례상 생략)를 사용하여 표현할 수도 있습니다.

double d1 = 123.4;
 
// same value as d1, but in scientific notation
double d2 = 1.234e2;
float f1  = 123.4f;

 

Character and String Literals

char String 유형의 리터럴에는 모든 유니코드(UTF-16) 문자가 포함될 수 있습니다. 편집기 및 파일 시스템에서 허용하는 경우 코드에서 이러한 문자를 직접 사용할 수 있습니다. 허용되지 않는 경우 \u0108(곡선이 있는 대문자 C) 또는 “S\u00ED Se\u00F1or”(스페인어로 시 세뇨르)와 같은 “Unicode escape”를 사용할 수 있습니다. char 리터럴에는 항상 ‘작은따옴표’를, String 리터럴에는 ‘큰따옴표’를 사용하세요. 유니코드 이스케이프 시퀀스는 프로그램 내 다른 곳(예: 필드 이름 등)에서도 char 또는 String 리터럴뿐만 아니라 사용할 수 있습니다.

Java 프로그래밍 언어는 charString 리터럴에 대한 몇 가지 특수 이스케이프 시퀀스도 지원합니다: \b(백스페이스), \t(탭), \n(줄 바꿈), \f(폼 피드), \r(캐리지 리턴), \"(큰따옴표), \'(작은따옴표) 및 \\(백슬래시).

모든 참조 타입의 값으로 사용할 수 있는 특수 null 리터럴도 있습니다. null 리터럴은 원시 타입의 변수를 제외한 모든 변수에 할당할 수 있습니다. null 값으로 할 수 있는 작업은 그 존재 여부를 테스트하는 것 외에는 거의 없습니다. 따라서 null은 프로그램에서 어떤 객체를 사용할 수 없음을 나타내는 마커로 자주 사용됩니다.

마지막으로, 유형 이름에 ‘.class’를 추가하여 형성되는 _class 리터럴_이라는 특수한 종류의 리터럴도 있습니다(예: String.class). 이것은 타입 자체를 나타내는 객체, 즉 Class 타입의 객체를 가리킵니다.

 

숫자 리터럴에 밑줄 문자 사용

Java SE 7 이상에서는 숫자 리터럴의 자릿수 사이에 밑줄 문자(_)를 얼마든지 표시할 수 있습니다. 이 기능을 사용하면 예를 들어 숫자 리터럴의 숫자 그룹을 구분하여 코드의 가독성을 향상시킬 수 있습니다.

예를 들어 코드에 자릿수가 많은 숫자가 포함된 경우 쉼표나 공백과 같은 문장 부호를 구분 기호로 사용하는 것과 유사하게 밑줄 문자를 사용하여 세 개 그룹으로 자릿수를 구분할 수 있습니다.

다음 예는 숫자 리터럴에 밑줄을 사용할 수 있는 다른 방법을 보여줍니다:

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi =  3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

밑줄은 숫자 사이에만 넣을 수 있으며 다음 위치에는 밑줄을 넣을 수 없습니다:

  • 숫자의 시작 또는 끝
  • 부동 소수점 리터럴의 소수점 옆
  • F 또는 L 접미사 앞
  • 숫자 문자열이 예상되는 위치

다음 예는 숫자 리터럴의 유효한 밑줄 위치와 유효하지 않은 밑줄 위치를 보여줍니다:

// Invalid: cannot put underscores
// adjacent to a decimal point
float pi1 = 3_.1415F;
// Invalid: cannot put underscores
// adjacent to a decimal point
float pi2 = 3._1415F;
// Invalid: cannot put underscores
// prior to an L suffix
long socialSecurityNumber1 = 999_99_9999_L;
 
// OK (decimal literal)
int x1 = 5_2;
// Invalid: cannot put underscores
// At the end of a literal
int x2 = 52_;
// OK (decimal literal)
int x3 = 5_______2;
 
// Invalid: cannot put underscores
// in the 0x radix prefix
int x4 = 0_x52;
// Invalid: cannot put underscores
// at the beginning of a number
int x5 = 0x_52;
// OK (hexadecimal literal)
int x6 = 0x5_2;
// Invalid: cannot put underscores
// at the end of a number
int x7 = 0x52_;