프리미티브 타입 종류와 값의 범위 그리고 기본 값
Java에는 int, byte, short, long, float, double, boolean, char와 같이 8가지의 Primitive type이 있다.
Primitive type 값의 범위와 기본값
타입 | 할당되는 메모리 크기 | 기본값 | 데이터의 표현 범위 | |
논리형 | boolean | 1 byte | false | true, false |
정수형 | byte | 1 byte | 0 | -128 ~ 127 |
short | 2 byte | 0 | -32,768 ~ 32,767 | |
int | 4 byte | 0 | -2,147,483,648 ~ 2,147,483,647 | |
long | 8 byte | 0L | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | |
실수형 | float | 4 byte | 0.0F | (3.4 X 10^-38 ) ~ (3.4 X 10^38 ) 의 근사값 |
double | 8 byte | 0.0 | (1.7 X 10^-308 ) ~ (1.7 X 10^308 ) 의 근사값 | |
문자형 | char | 2 byte | '\u0000' | 0 ~ 65,535 |
프리미티브 타입과 레퍼런스 타입
원시 타입(Primitive type)과 참조 타입(Reference type)
- 원시 타입은 실제 값을 저장하는 반면 참조 타입은 참조하는 객체의 주소를 저장
리터럴
리터럴이란
- 고정 값을 나타내는데 사용되는 데이터
- Like 상수
int a = 1;
float b =2.5;
char c = 'F';
- 여기서 1 2.5 'F' 는 리터럴이다.
boolean 리터럴
boolean 리터럴은 boolean 타입의 데이터를 초기화하는데 사용된다
boolean visited = false;
boolean check = true;
- false true 두 개의 boolean 리터럴
Integer 리터럴
Java에서 Integer 리터럴은 4가지 유형이 있다.
// binary, 2진수
int binaryNumber = 0b10010;
// octal, 8진수
int octalNumber = 027;
// decimal, 10진수
int decNumber = 56;
// hexadecimal, 16진수
int hexNumber = 0x2F;
- 2진수, 8진수, 10진수, 16진수 4가지 유형의 Integer 리터럴이 있다
- Java에서 binary(2진수)는 0b 로 시작하고, 8진수는 0, 16진수는 0x 로 시작한다.
부동 소수점 리터럴
부동 소수점 리터럴은 분수 형식이나 지수 형식이 있는 숫자 리터럴이다.
Class Main {
public static void main(String[] args) {
double doubleNumber = 3.4;
float floatNumber = 3.4F;
double doubleScientific = 3.445e2;
System.out.println(doubleNumber); // prints 3.4
System.out.println(floatNumber); // prints 3.4
System.out.println(doubleScientific); // prints 344.5
}
}
문자 리터럴
문자 리터럴은 작은 따옴표로 묶인 유니코드 문자다
char letter = 'a';
- 이스케이프 시퀀드 또한 문자 리터럴로 사용할 수 있다. (’\\b’, ‘\\t’, ‘\\n’)
문자열 리터럴
문자열 리터럴은 큰 따옴표로 묶인 문자다.
String hello = "Hello World!";
String ajax = "AJAX!!!!!";
str ajax 두 개의 문자열 리터럴이 있다.
변수 선언 및 초기화하는 방법
선언은 유형 및 이름과 함께 변수를 정의하는 프로세스이다.
초기화는 값을 할당하는 것이다.
int id; // id 변수를 선언
id = 1; // id 값 초기화
객체 초기화
객체는 new 키워드를 사용하여 초기화를 한다. new 키워드를 사용함으로서 생성자를 호출하고 메모리에서 객체를 초기화한다.
Variable Scope에 따른 초기화
인스턴스 및 클래스 변수는 초기화할 필요가 없다. 이러한 변수는 선언과 동시에 다음과 같은 기본값이 지정된다.
지역 변수는 기본 값이 없고 컴파일러에서 초기화되지 않은 값을 사용하도록 허용하지 않으므로 사용하기 전에 초기화해야 한다.
public void print() {
int i;
System.out.println(i);
}
- print() 메서드의 지역변수 i 는 초기화되지 않았기 때문에 실행했을 때 컴파일러가 에러를 발생시킨다.
초기화 순서
Java에서 초기화 순서는 다음과 같다.
- static (정적 변수 및 정적 이니셜라이저)
- instance (인스턴스 변수 및 인스턴스 이니셜라이저)
- constructor (생성자)
etc
여기서 다루지 않지만 객체를 생성할 때 new 키워드 이외에도 리플렉션을 사용하여 객체를 만들 수 있다고 한다.
변수의 스코프와 라이프타임
변수는 클래스, 메서드 또는 블록 내에서 선언되고 정의된다. 블록이나 메서드 내부에서 선언된 변수는 외부에서 볼 수 없다.
- 일반적으로 중괄호 { } 는 범위를 정의한다
- 메서드 외부 클래스에 정의된 모든 변수는 모든 멤버 메서드에서 사용할 수 있다
- 메서드에 멤버와 동일한 지역 변수가 있을 때 this 키워드를 사용하여 현재 클래스 변수를 참조할 수 있다
- Loop 종료 후 변수를 읽으려면 Loop 시작 전에 해당 변수를 선언해야 한다
Instance Variables
클래스 내부와 모든 메서드 및 블록 외부에 선언된 변수는 인스턴스 변수다
범위
정적 메서드를 제외한 클래스 전체
수명
객체가 메모리에 머무를 때까지
Class Variables
클래스 내부, 모든 블록 외부에 선언되고 정적으로 표시된 변수를 클래스 변수라고 한다
범위
클래스 내 어디에서나 선언할 수 있지만 메서드 외부에서 선언해야 한다
수명
- 프로그램이 끝날 때까지
- 클래스가 메모리에 올라가있는 동안
Local Variables
인스턴스 및 클래스 변수가 아닌 다른 모든 변수는 메서드의 매개 변수를 포함하여 지역 변수로 취급된다
범위
지역 변수의 범위는 선언된 블록 내에 있다
수명
선언된 블록을 떠날 때까지
타입 변환, 캐스팅 그리고 타입 프로모션
- 이미 선언한 변수에 다른 데이터 유형의 값을 할당하면 두 유형이 서로 호환되지 않을 수 있다
- 데이터 유형이 호환되는 경우 Java는 자동 유형 변환을 수행하고, 그렇지 않은 경우엔 명시적으로 캐스팅 또는 변환해주어야한다.
data type Bits Acquired In Memory
boolean | 1 |
byte | 8 (1 byte) |
char | 16 (2 bytes) |
short | 16 (2 bytes) |
int | 32 (4 bytes) |
long | 64 (8 bytes) |
float | 32 (4 bytes) |
double | 64 (8 bytes) |
Type Conversion (타입 변환)
타입 (확장) 변환은 두 가지 데이터 유형이 자동으로 변환될 때 발생한다.
- 두 데이터 유형은 호환된다
- 더 작은 데이터 유형의 값을 더 큰 데이터 유형에 할당할 때 타입 변환이 가능하다
class TypeConversionEx {
public static void main(String[] args) {
int i = 100;
long l = i;
float f = l;
System.out.println("int: " + i); // 100
System.out.println("long: " + l); // 100
System.out.println("float: " + f); // 100.0
}
}
Java에서 숫자 데이터 유형은 서로 호환되지만 숫자 유형에 char 혹은 boolean 으로의 자동 변환은 지원되지 않는다. 숫자 데이터 유형은 Byte → Short → Int → Long → Float → Double 순서로 타입 변환이 가능하다.
Type Casting
더 큰 데이터 유형의 값을 더 작은 데이터 유형에 할당하려면 캐스팅을 명시적으로 해주어야한다
- 더 큰 데이터 유형이 더 작은 데이터 유형으로는 자동 변환이 이루어지지 않을 때 캐스팅을 한다
class TypeCastingEx {
public static void main(String[] args) {
char ch = 'c';
int num = 88;
ch = num;
}
}
- 더 큰 데이터 유형인 int (4 bytes)를 더 작은 데이터 유형인 char (2 bytes)로 변환하고자 했기에 에러가 발생한다
class TypeCastingEx2 {
public static void main(String[] args) {
double doubleValue = 100.04;
long longValue = (long) doubleValue;
int intValue = (int) longValue;
System.out.println("Double Value :" + doubleValue); // 100.04
System.out.println("Long Value :" + longValue); // 100
System.out.println("Int Value :" + intValue); // 100
}
}
- 이와 같이 더 작은 데이터 타입으로 변환하고자 할 때는 변환할 데이터 타입을 명시해주어야 캐스팅이 된다
Type Promotion
- 작은 데이터 타입을 더 큰 데이터 타입으로 승격(?) 시킬 수 있다.
- 예로 int가 long, float, double과 같은 더 큰 데이터 타입으로 승격될 수 있다.
- Type Promotion은 더 큰 크기의 데이터 타입 인수를 받는 메서드가 더 작은 데이터 타입으로 호출될 때 수행된다.
class TypePromotionEx {
public void something(double a) {
System.out.println("안녕하시렵니까?");
}
public static void main(String[] args) {
something(2);
}
}
- 위의 예제에서는 something() 메서드를 호출하기 위해 정수를 인수로 넣어줬지만 double 타입으로 promotion 되어 메서드가 수행된다
1차 및 2차 배열 선언하기
배열이란
- Java의 배열은 단일 타입의 고정된 수의 데이터를 보유하는 객체
- 배열이 선언되면 배열의 참조가 생성된다
- 배열의 길이는 배열이 생성될 때 설정된다
- 생성된 배열의 길이는 고정이다
- 배열의 인덱스는 0부터 시작한다, 9번째 element는 8번째 인덱스에 저장된다
배열 선언
- 배열 선언에는 배열 타입과 이름 두 가지 요소로 구성된다
- type[]. type에는 데이터 타입이 들어가게 되고, 대괄호는 이 변수가 배열을 보유하고 있음을 나타내는 특수 기호이다
- 배열의 선언을 통해 실제로 배열이 생성되지 않는다
- 단순히 이 변수가 지정된 타입의 배열을 가질 거라는 걸 컴파일러에게 알린다
int[] arr; // 배열이 선언된 상태, 배열의 참조가 생성되었지만 배열이 생성된 것은 아니다. int 타입의 배열을 만들거라는 걸 컴파일러에게 알릴 뿐이다.
배열 생성
- 배열을 만들 땐 new 키워드를 사용한다.
int[] arr;
arr = new int[10]; // new 키워드를 이용하여 int 타입의 배열 변수에 메모리를 할당한 상태
- 선언과 동시에 생성 또한 가능하다
int[] arr = new int[10];
2차원, 다차원 배열
다차원 배열의 크기
- 다차원 배열에 저장할 수 있는 요소의 총 개수는 모든 차원의 크기를 곱하여 계산할 수 있다
- int[][] arr = new int[10][20] 은 총 (10 * 20) = 200개의 요소를 저장할 수 있다
- int[][][] arr = new int[5][10][20] 은 총 (5 * 10 * 20) = 1000개의 요소를 저장할 수 있다
다차원 배열 요소에 접근
- 2차원 배열을 예로 들면, 2차원 배열의 요소는 일반적으로 arr[i][j]로 참조되며, 여기서 i 는 행 번호, j 는 열 번호가 된다
- 2차원 배열은 행 번호가 0에서 (i - 1) 까지이고
- 열 번호는 0에서 (j - 1)가 된다
타입 추론, var
Type Inference
- Java Compiler가 타입을 추론하는 것을 Type Inference라고 한다. 컴파일러는 추론을 위해 메서드 호출과 선언을 확인한다.
- 타입 추론을 통해 Generic 메서드를 사용할 때 특정 타입을 명시하지 않은 채로 호출할 수 있다 (Java SE 8부터 적용)
public Class GenericEx {
List<String> list = new ArrayList<String>(); // ArrayList() 를 호출하면서 type argument String을 명시
List<String> list2 = new ArrayList<>(); // Java Compiler가 타입 추론을 해주기 때문에 type argument를 명시하지 않아도 된다
}
var
- Java 10부터 var가 도입되었다
- var 키워드를 이용해 Type Inference이 주변 컨텍스트를 기반으로 하여 데이터 타입을 자동으로 감지한다
- var 키워드로 모든 데이터 타입을 선언할 수 있다
class varEx {
public static void main(String[] args) {
var a = 100;
var b = 1.90;
var c = 'a';
var d = "Hello World!";
var e = false;
System.out.println(a); // 100
System.out.println(b); // 1.9
System.out.println(c); // a
System.out.println(d); // Hello World!
System.out.println(e); // false
}
}
- var 타입에 여러 데이터 타입을 선언해보면 var 키워드가 자동으로 데이터 타입을 감지해준다
https://www.programiz.com/java-programming/variables-literals
https://www.baeldung.com/java-initialization
https://www.geeksforgeeks.org/variable-scope-in-java/
https://www.geeksforgeeks.org/type-conversion-java-examples/
https://www.geeksforgeeks.org/automatic-type-promotion-in-overloading-in-java/
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
https://live-everyday.tistory.com/207
https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
'Java' 카테고리의 다른 글
5주차 클래스 (0) | 2022.08.18 |
---|---|
제어문 (0) | 2022.08.12 |
연산자 (0) | 2022.08.10 |
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가 (9) | 2022.07.24 |
자바 프로그램의 개발과 구동 (0) | 2022.01.17 |