🎯 목표
자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.
☑️ 학습할 것
- 프리미티브 타입 종류와 값의 범위 그리고 기본 값
- 프리미티브 타입과 레퍼런스 타입
- 리터럴
- 변수 선언 및 초기화하는 방법
- 변수의 스코프와 라이프타임
- 타입 변환, 캐스팅 그리고 타입 프로모션
- 1차 및 2차 배열 선언하기
- 타입 추론, var
1. 프리미티브 타입 종류와 값의 범위 그리고 기본 값
프리미티브 타입(원시 타입)의 종류는 다음과 같다.
구분 | 데이터형 | 범위 | 크기(Byte) | 초기값 |
---|---|---|---|---|
논리형 | boolean | 1 or 0 (참 혹은 거짓) | 1byte | false |
문자형 | char | \u0000~\uffff | 2byte | \u0000 |
정수형 | byte | -128 ~ 127 | 1byte | 0 |
short | -32,768 ~ 32,767 | 2byte | 0 | |
int | -2^31 ~ 2^31 -1 (±21억) | 4byte | 0 | |
long | -2^63 ~ 2^63 -1 (±920경) | 8byte | 0L | |
실수형 | float | 7자리의 정밀도 | 8byte | 0.0d |
double | 16자리의 정밀도 | 8byte | 0.0f |
여기까지 작성하면서 의문이었던 점이 하나 있었다.
논리형 타입인 boolean은 참과 거짓, 단 두가지 값만 표현할 수 있으면 되는데 왜 1byte를 사용하는 지 궁금해서 Stack Overflow에서 찾아보았고 내용은 다음 포스트에서 조금 더 자세하게 작성해보자.
2. 프리미티브 타입과 레퍼런스 타입
java에는 프리미티브 타입(원시 타입) 과 레퍼런스 타입이 있다.
프리미티브 타입
- boolean, char, byte, short, int, long, unsigned int, unsigned long...
- 초기값이 있지만, null 값을 가질 수 없다.
- stack 에 값 저장.
레퍼런스 타입
- Class, Interface, Enum, String, Array 등등...
- 초기값이 없고, null 값을 가질 수 있다.
- Heap 에 값이 저장되어있는 곳의 주소를 저장.
- Wrapper Class는 위의 프리미티브 타입을 레퍼런스 타입으로 정의한 것.
프리미티브 타입 | 래퍼 클래스 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
프리미티브 타입 -[박싱]-> 래퍼 클래스
래퍼 클래스 -[언박싱]-> 프리미티브 타입
Integer x = new Integer(90); // boxing
Integer y = new Integer(90);
int a = num.intValue(); // unboxing
int b = num // auto unboxing
// 프리미티브 타입 값과 래퍼 클래스의 값 비교
x == a // True
x.equals(a) // True
x.equals(y) // True
x == y // False
래퍼 클래스끼리의 비교는 내부의 값을 비교해야 하기 때문에 == 연산자로는 비교가 불가능하다. (래퍼 클래스의 값은 주소를 담고 있기 때문에)
3. 리터럴 (literal)
우리가 알고 있던 상수의 개념과 같다, 그러나 프로그래밍에서는 '값을 한 번 저장하면 변경할 수 없는 저장공간'이라는 뜻으로 상수(constant)를 정의하였기 때문에 리터럴이라고 한다. (그 자체로 값을 의미한다.)
4. 변수 선언 및 초기화하는 방법
수학에서 '변수(變數)'를 '변하는 수'라고 정의하지만 프로그래밍언어에서의 변수(variable)란, 값을 저장할 수 있는 메모리상의 공간을 의미한다.
출처: Java의 정석
int age;
double height = 177.5;
첫 번째 코드는 int 타입의 변수 age를 선언한 것이고
두 번째 코드는 double 타입의 변수 height를 선언하고 177.5로 초기화하는 코드이다.
int 타입의 초기값은 0이기 때문에 age 변수의 값은 0이다.
컴파일 단계에서 에러 발생
error: incompatible types: possible lossy conversion from int to byte
byte a = 3;
byte b = 6;
=> OK
a + 3
a + b
=>ERROR
5. 변수의 스코프와 라이프타임
먼저 변수의 스코프란, 변수가 사용될 수 있는 범위를 말하는데 다음의 예시를 보자
public class ScopeTest {
String classVal = "Class";
static String staticVal = "Static";
public void method01() {
String methodVal = "method";
System.out.println(methodVal);
}
public static void main(String[] args) {
System.out.println(staticVal);
ScopeTest s = new ScopeTest();
System.out.println(s.classVal);
}
}
변수는 중괄호 { }
블록 내에서 선언되고 사용된다.
스코프 밖의 변수에는 접근할 수가 없다. -> methodVal
은 해당 메소드 안에서만 접근, 사용이 가능하다.
단, static
으로 정의된 변수는 인스턴스에 관계없이 같은 값을 갖는다.
static type이 아니면 인스턴스로 정의를 해 주어야 사용할 수 있다. (s.classVal 부분)
6. 타입 변환, 캐스팅 그리고 타입 프로모션
타입 변환이란 어떠한 타입으로 선언된 변수를 다른 타입으로 바꾸는 것을 말한다.
예를들면
int iVal = 10;
double dVal = iVal;
의 경우 double로 선언된 dVal에 정수값인 10을 컴파일러가 자동으로 10.0이라는 값으로 변환시켜준다.
이를 묵시적 형 변환 또는 타입 프로모션이라고 한다.
다음과 같은 예를 접하는 경우도 있다.
int a = 3;
int b = 5;
// a를 b로 나눈 값을 사용하기 위해 double 변수 div를 선언
double div = a / b;
해당 div
변수의 값은 0이 나온다, 하지만 우리가 기대했던 값은 0.6이다.
이러한 현상이 일어나는 이유는 int타입의 변수끼리의 연산을 통해 나온 값 또한 int이기 때문에
소수점 아래는 버려지기 때문이다. 이를 해결하기위해 다음과 같이 작성해준다.
int a = 3;
int b = 5;
// a를 b로 나눈 값을 사용하기 위해 double 변수 div를 선언 + a 변수를 double타입으로 변환
double div = (double)a / b;
위와같이 임의로 변수의 타입을 변환시키는 것을 명시적 형 변환 또는 캐스팅 이라고 한다.
위의 연산에서 a / b 는 3.0 / 5 가 되며
double 타입과 int 타입의 연산의 결과값이 타입 프로모션을 통해 double타입으로 div 변수에 들어가는 것이다.
7. 1차 및 2차 배열 선언하기
1차원 배열
배열에 대해서 알아보자.
배열이란 특정 타입의 변수를 연속으로 작성한 것을 말하는데, 변수들은 메모리상으로도 연속적으로 위치하기 때문에 임의 접근(Random Access)가 가능하다.
int[] members1;
members1 = new int[3];
int[] members2 = {1,2,3,4};
위의 과정의 결과로부터 두가지를 알 수 있다.
- int 배열을 선언하면 0으로 초기화가 된다.
- 배열을 선언과 동시에 초기화를 할 수 있다.
2차원 배열
2차원 배열 또한 비슷한 방법으로 선언 및 사용가능하다.
int[] members1;
int[] members2 = {{1,2,3},{2,4,6},{3,6,9},{4,8,12}};
8. 타입 추론, var
var 변수는 선언되는 시점에 초기화가 필요하다, 만일 초기화를 해 주지 않는다면 다음의 에러를 발생한다.
public class MyClass {
public static void main(String args[]) {
var hello;
}
}
=========================================
/MyClass.java:3: error: cannot infer type for local variable hello
var hello;
^
(cannot use 'var' on variable without initializer)
1 error
var 변수는 초기화 없이 사용할 수 없습니다.
라고 한다.
또한 초기화 되는 시점에 타입추론을 통해 설정된 타입이 고정되기 때문에
var 변수에 int타입으로 초기화를 한 다음에 해당 변수에 다른 타입을 넣을 때에도 에러가 난다.
public class MyClass {
public static void main(String args[]) {
var intVal = 33;
intVal = 3.14;
}
}
=========================================
/MyClass.java:4: error: incompatible types: possible lossy conversion from double to int
intVal = 3.14;
^
1 error
'Study > Java' 카테고리의 다른 글
Java의 boolean의 크기는 몇일까? (0) | 2021.05.09 |
---|---|
자바 스터디 - 1주차 (JVM, java, JDK, JRE, 바이트코드) (0) | 2021.05.09 |