목표
자바의 프리미티브 타입 종류와 변수와 배열 선언하는 방법 이해하기
학습할 것
- 프리미티브 타입 종류와 값의 범위 그리고 기본 값
- 프리미티브 타입과 레퍼런스 타입
- 리터럴
- 변수 선언 및 초기화하는 방법
- 변수의 스코프와 라이프타임
- 타입 변환, 캐스팅 그리고 타입 프로모션
- 1차 및 2차 배열 선언하기
- 타입 추론, var
프리미티브 타입
- 자바에는 총 8가지의 프리미티브 타입이있다.
- 이 표를 보자니 문득 궁금한 점이 있다. 왜 음수가 하나 더 많을까?
사실 양수와 음수 메모리는 동등하고 그렇기에 표현할수 있는 수는 동일하다.
하지만 0을 음수또는 양수 둘중 하나가 처리해야되는과정에서 양수가 담당을 하였다.
따라서 음수가 0을 제외한 수를 하나 더가짐으로써 많아 보일뿐이다. - 메모리크기와 값의 범위는 어떤 관계가 있을까?
byte로 예시를 들어보자. byte의 메모리 크기는 1byte = 8bit 이다. byte 맨앞의 bit는 양수,음수를 표현한다.
따라서 두번째 bit부터 마지막칸까지 총 7칸, 2의 7승만큼의 수를 표현할 수 있다. 그래서 -128~127 의 값의 범위가
나오는걸 볼 수 있다.
- 실수형의 E38은 10^38을 의미한다. 그렇다면 궁금해지는게
int와 같은 메모리 크기를 가진 float은 어떻게 더 큰 범위의 수를 표현할수 있는것일까?
아래 표를 보면 이해가 쉽다. float은 정수형과 달리 값을 부호, 지수, 가수 이렇게 3개로 나눈다.
3.4*10^38을 예시로 들면 3.4가 가수, 38이 지수이다. 이렇다보니 같은 메모리크기를 가진
integer타입보다 훨씬 큰 범위의 수를 표현한다. 대신에 오차가 발생할 수 있다.
정밀도라는 것이 중요한데 정밀도를 결정하는 것은 가수의 자리수이다.
원래 가수는 23자리지만 정규화를 통해 24자리까지 저장가능 10^7< 2^24 <10^8 이므로 정밀도가
7자리이다.
- double은 이름 그대로 가수의 자리수가 float보다 약 2배기이 때문에 double이다.
정밀도도 약 2배인 15자리이다. 그래서 보통은 double(실수형 default값)을 사용한다 - Long으로도 표현이 불가능한 큰 정수를 표현하고싶은경우: BigInteger 사용
자바 8버전부터 java.math에서 지원해주는 클래스로 엄청나게 큰 정수를 사용할때 쓴다.
따로 연산기호 사용이 불가능하기에 add(), substract(), multiply(), divide(), mod()와같은 메서드를
통해서 연산가능하다. 자세한건 따로 BigInteger 관련 글을 참고하기를 바란다.
아직 정리해놓은게 없어서 다른 도움되는 블로그 글(BigInteger,BigDecimal 관련 사용법) 링크를
놓겠다.
https://technote-mezza.tistory.com/104
프리미티브 타입과 래퍼런스 타입
프리미티브 타입
- 정수, 실수, 문자, 논리 리터럴 등의 실제 데이터 값을 저장하는 타입
래퍼런스 타입
- 객체의 번지(주소)를 참조하는 타입
※별도의 내용: 이제 저번 게시글에서 언급했던 가비지 컬렉터 내용 얘기를 꺼내보면 힙에서 참조받지 않은 객체를 삭제한다고 말했었는데 위에 그림을 예시로 들면 car이라는 객체가 참조되지않아 추후에 mark and sweep 과정에서 제거가 된다.
리터럴
- 리터럴이란?
리터럴은 코드에서 사용되는 고정된 값으로, 변수에 할당하거나 사용할 수 있는 데이터의 표현 형태를 의미한다.
정수, 실수, 문자, 문자열, boolean 등이 포함된다.
//리터럴 예시
char ch = 'C';
bybe b = 20;
int i = 30000;
double d = 20.7456;
boolean forward = true;
- 각각 형태에서의 리터럴
- 정수
10진수로만 표현가능한게 아니라 2진수 16진수도 표현가능하다.
(ex. 0b1001, 0x52) - 실수
floating-point라고 해서 f로 표현한다.
(ex. 123.45f)
- 정수
변수 선언 및 초기화하는 방법
- 선언: 저장공간을 확보
아래 예시를 보면 int형 변수 a를 선언함으로써 4byte 공간을 확보했다.
하지만 따로 초기화를 안했기때문에 의미없는 쓰레기값이 들어가있다. 그렇기에 선언 후에 초기화를 해줘야한다.
int a; //4byte 공간 확보
- 초기화
a = 10; // 초기화
- 선언과 초기화
int a = 10; //변수의 선언과 초기화를 한줄에 하는게 가능
변수의 스코프와 라이프타임
변수의 스코프: 해당 변수의 영역 범위를 뜻한다.
라이프타입: 해당 변수가 메모리에서 언제까지 살아있는지를 의미한다.
변수의 스코프
- 인스턴스 변수
- 객체마다 각기 다른 값을 가지는 변수이다.
- 라이프타임: 클래스를 인스턴스화한 객체가 메모리에서 사라질때까지이다.
- 클래스 변수
- 클래스 안에서 선언되었고 static 키워드가 포함되어 선언된 변수이다.
- 라이프타임: 프로그램 종료시까지 지속된다.
- 로컬 변수
- 인스턴스, 클래스 변수가 아닌 변수로 block내부가 영역 범위이다.
- 해당 변수가 선언된 블록이 실행되는 동안에만 유효하다.
아래 코드는 위에 3가지의 변수 스코프를 보여주는 예시이다.
public class example {
private int instanceVar; //인스턴스
static int classVar; //클래스
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 로컬 변수
int localVar = 10; // 메서드 내에서만 유효한 지역 변수
// 클래스 변수 사용
classVar = 30;
// 로컬 변수 사용
System.out.println(localVar);
}
}
타입 변환, 캐스팅 그리고 타입 프로모션
타입 변환
데이터의 형식을 다른 데이터 타입으로 변환하는 과정이다. 아래의 예시를 참고하자.
int intValue = 123;
double do = 3.14;
String str = Integer.toString(intValue); //정수를 문자열로 변환 "123"이됨
double doubleValue = (double) intValue; //정수를 실수로 변환 123.0 이됨
String str = Double.toString(do); //실수를 문자열로 변환 "3.14"가됨
String strValue = "456";
int intValue = Integer.parseInt(strValue); //문자열을 정수로 변환 정수 456이됨
타입 캐스팅
- 크기가 더 큰 자료형을 크기가 더 작은 자료형에 대입하는 것을 의미한다.
(ex. int(4byte)타입의 데이터를 byte(1byte)타입으로 대입하는 경우) - 물론 데이터 크기가 더 큰것이 작은 타입으로 들어가기때문에 데이터의 손실이나 변형이 발생한다.
(ex. byte는 -128~127의 수만 표현할 수 있는데 10만 숫자를 int형으로 담았다가 byte로 타입캐스팅하면
데이터의 변형이 온다.)
타입 프로모션
- 캐스팅과 반대로 크기가 더 작은 자료형을 더 큰 자료형에 대입하는 것을 의미한다.
(ex. byte(1byte)타입의 데이터를 int(4byte) 타입에 대입하는 경우) - 더 작은 자료형에도 문제없던 데이터라면 더 큰 자료형에서는 당연히 문제가 없다.
따라서 캐스팅과 다르게 데이터 손실이나 변형이없다. - 자동으로 변환이 가능하다.
byte a = 5;
int b = a;
System.out.println(b); //5
1차 및 2차 배열 선언하기
배열
- 동일한 타입의 데이터를 연속된 공간에 저장하기 위한 자료구조이다.
- 유의해야할점은 배열은 시작은 0이다.(배열 맨앞의 값을 찾을려면 arr[0] 이라고 해야한다.)
배열의 선언과 초기화
int[] arr; //1차 배열 선언
int arr []; //위랑 동일
int[] arr = new int[10]; //크기가 10인 정수형 배열 선언
int[] arr = {1,2,3}; //정수형 배열 선언과 초기화
//2차 배열의 선언
int[][] arr; //2차 배열 선언
int[][] arr = new int [3][3]; //3행 3열 크기의 2차 배열 선언 [행][열]순이다.
추가로 int형 말고도 char, String등 다른 타입으로도 배열 선언 과 초기화가 가능하다.
String str = "Hello";
char[] chArr = str.toCharArray(); //크기가 5인 문자 배열 선언 및 초기화
System.out.println(chArr[1]); //'e'가 출력된다
String[] strArr = new String[10]; //크기가 10인 문자열 배열 선언
strArr[0] = str;
타입 추론, var
- var: 자바 10부터 도입된 타입추론 타입이다.
특징으로는 변수의 타입을 컴파일러가 자동으로 추론하여 선언할 수 있다.
// 이전의 타입 선언 방식
String message = "Hello, Java!";
// 타입 추론 방식(자바가 변수 message의 타입을 String으로 잡아줌)
var message = "Hello, Java!";
- var의 사용 특징
- Var은 초기화 없이 사용할 수 없다.
- 타입 변수에는 null이 들어갈 수 없다. 또한 초기값이 없으면 안된다.
- 로컬 변수에만 선언이 가능하다.
- 배열을 선언할 때, var대신 타입을 명시해줘야한다.
- 람다표현식에는 명시적인 타입을 지정해줘야한다.
//람다표현식에서 명시적인 타입지정이 제대로 이뤄지지않는 경우
Consumer<?> printLength = (var str) -> System.out.println(str.length());
//제대로 표현된 경우
//Consumer의 타입을 String으로 했기때문에 가능
Consumer<String> printLength = (var str) -> System.out.println(str.length());
//위와 동일한 표현, 근데이제 뒤에 String str 라고 변수선언을 했기때문에 Consumer<?>도 가능
Consumer<String> printLength = (String str) -> System.out.println(str.length());
'자바(Java)' 카테고리의 다른 글
[자바] HashSet 중복값 처리 과정, 배열로 변경하는 법 (0) | 2023.08.08 |
---|---|
[자바] 자바 조건문과 반복문, JUnit 5 (0) | 2023.08.05 |
[자바] 자바 연산자 (0) | 2023.07.29 |
[자바] JVM, 자바 실행방법 (2) | 2023.07.16 |
[Java] 자바 StringBuilder 사용법 (0) | 2023.03.19 |