본문 바로가기
Java관련/Java

Java 데이터 타입, 변수, 배열

by devstep 2022. 7. 31.

자바 데이터 타입, 변수, 배열

학습 목표

자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.

  • 프리미티브 타입 종류와 값의 범위 그리고 기본 값
  • 프리미티브 타입과 레퍼런스 타입
  • 리터럴
  • 변수 선언 및 초기화하는 방법
  • 변수의 스코프와 라이프타임
  • 타입 변환, 캐스팅 그리고 타입 프로모션
  • 1차 및 2차 배열 선언하기
  • 타입 추론, var

1 프리미티브 타입 종류와 값의 범위 그리고 기본 값

기본형 Primitive type

  • char : 문자형, 문자의 유니코드(정수 2byte)가 저장된다. 그러므로 정수형, 실수형과 연산도 가능
  • int : 정수형. CPU가 가장 효율적으로 처리할 수 있는 타입, 대략 20억까지 표현 가능.
  • long : 7~9자리 수 계산할 때는 넉넉하게 long(19자리)로 변수 선언
  • byte, short : 정수형. 메모리를 절약하려면 해당 타입 사용.
  • 실수형 : 저장형식이 정수형과 다르다. 오차가 발생할 수 있는 단점
    • 실수형은 정밀도(precision)가 중요.
    • float : 정밀도 7자리
    • double : 정밀도 15자리
  • ★ [중요] 기본형의 종류와 크기
종류 /크기 1byte(8bit) 2byte 4byte 8byte
논리형 boolean      
문자형   char    
정수형 byte short int long (접미사L/l)
실수형     float (접미사F/f) double
  • 예시
  • long longNumber = 2L; float floatNumber = 2f;
  • 기본형의 크기와 범위
자료형 저장 가능한 값의 범위 크기(bit)
boolean false, true 8bit
char \u0000 ~ \uffff (0216 -1, 0 65,535) 16bit
byte -128~127(-27 ~ 27-1) 8bit
short -32,768 ~ 32,767 (-215 ~ 215-1) 16bit
int -2,147,483,648 ~ 2,147,483,647 (-231 ~ 231-1) 32bit
long -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 (-263 ~ 263-1) 64bit
float 1.4E-45 ~ 3.4E38 (1.4 * 10-45 ~ 3.4 * 1038) 32bit
double 4.9E-324 ~ 1.8E308 (4.9 * 10-324 ~ 1.8 * 10308) 64bit
  • 특수문자 표현법
특수문자 문자 리터럴
tab \t
backspace \b
form feed \f
new line(line feed) \n
carriage return \r 같은 줄 맨 앞의 위치로
역슬래쉬\ \
작은따옴표 \’
큰따옴표 \”
유니코드 \u유니코드 (예)char ch= ‘\u0041’

정수형

  • long 타입의 범위를 벗어날 경우는 BigInteger 클래스를 사용한다.
  • 정수형의 오버플로우

타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우(overflow)라 한다.

오버플로우가 발생해도 오류가 발생하지는 않지만 원하는 값을 얻을 수 없으니 충분한 크기의 데이터 타입을 선택한다.

  • 부호 없는 정수의 오버플로우

표현할 수 있는 최대값에서 1을 더하면 최소값이 되고,
최소값에서 1을 빼면 최대값이 된다.

  • 부호 있는 정수의 오버플로우

부호 비트가 0에서 1이 될 때 오버플로우 발생

실수형

  • 실수형은 소수점도 표현해야 하므로
    얼마나 0에 가깝게 표현 할 수 있는가도 중요하다.
  • 실수형은 정수형과 표현형식이 다르다.
  • 실수를 아래와 같은 형태로 부호(Sign), 지수(Exponent), 가수(Mantissa) 로 이루어져 있다
    • +-M * 2E
  • 7자리 정밀도 float
    • 1234.567 = 1.234567 * 103
    • 0.00001234567 = 1.234567 * 10-5
    • 1234567000 = 1.234567 * 109
  • 부호(Sign)
    • 2의 보수법을 사용하지 않기 때문에 부호비트만 바꾸면 양/음의 실수로 전환할 수 있다.
  • 가수(Mantissa)
    • 부동소수점의 오차
      • 무한소수가 존재
      • 유한소수일 때도 2진수로 변환 시 자리수 한정으로 버려지는 값들에 의해 오차가 발생
  • 정규화
    • 2진수로 변환된 실수를 저장할 때는 먼저 1.xxx * 2n의 형태로 변환하는데, 이 과정을 정규화라고 한다.
    • 정규화된 2진 실수는 항상 1.으로 시작하기 때문에 1.을 제외한 23자리(float의 경우)가 가수로 저장된다.

2 프리미티브 타입과 레퍼런스 타입

  1. 기본형 Primitive type
    • 값을 저장
  2. 참조형 Reference type
    • 객체 주소(memory address) 저장
    • 기본형 제외한 나머지 타입

3 리터럴

상수(constant)는 값을 저장할 수 있는 공간은 변수와 같지만 한 번 값을 저장하면 다른 값으로 변경할 수 없다.

상수는 리터럴에 의미있는 이름을 붙여서 코드의 이해를 쉽게 만든다.

상수 선언과 초기화

final int MAX_SPEED = 10;

리터럴(literal)

상수를 새롭게 정의했으므로, 수학에서 상수의 의미를 리터럴이라고 부른다.

10진수 외에도 2,8,16진수 리터럴을 변수에 저장할 수 있다.

  • 16진수 : 접두사 0X 또는 0x
    • int hexadecimalNumber = 0x10; //10진수로 16
  • 8진수 : 접두사 0
    • int octalNumber = 010; //10진수로 8
  • 2진수 : 접두사 0b (JDK1.7 추가)
    • int binaryNumber = 0b10; //10진수로 2

JDK1.7부터 리터럴 중간에 _를 넣을 수 있어 큰 수 표현할 때 가독성을 높힐 수 있다.

long bigNumber = 100_000_000_000L;
long hexnumber = 0xFFFF_FFFF_FFFF_FFFFL;

4 변수 선언 및 초기화하는 방법

변수 초기화

  • 클래스변수, 인스턴스변수 : 초기화 생략 가능
  • 지역변수 : 사용하기 전 반드시 초기화
    • 예시) int number = 0;
    • Date today = new Date(); //Date객체를 생성해서 그 주소를 today에 저장.

5 변수의 스코프와 라이프타임

  • 변수의 종류 : 클래스 변수, 인스턴스 변수, 지역변수
  • class Variables { int instanceVariable; //멤버변수 - 인스턴스 변수 static int classVariable; //멤버변수 - 클래 변수 (공유변수) void method() { int localVariable = 0; //지역변수 } }
  • 클래스 변수
    • 클래스가 메모리에 로딩될때 ~ 프로그램 종료될 때까지 유지
  • 인스턴스 변수
    • 인스턴스가 생성되었을 때 생성
    • 인스턴스는 독립적인 저장 공간 가지므로 인스턴스끼리 서로 다른 값을 가질 수 있다.
  • 지역변수
    • 메서드 내에 선언되어 메서드 내에서만 사용 가능.
    • 메서드 종료되면 소멸.
    • 반복문 블럭 내에 선언된 지역변수는 블럭 내에서만 사용 가능.

6 타입 변환, 캐스팅 그리고 타입 프로모션

다른 타입으로 변환는 것을 형변환(casting)이라고 한다.

서로 다른 타입간의 연산을 수행할 때는 먼저 타입을 일치시켜야 한다.

형변환 방법

  • (타입) 피연산자
  • double d = 92.3; int score = (int)d;

정수형 형변환

  • 큰 타입에서 작은 타입으로 변환
    • 값 손실(loss of data) 발생 가능성
  • 작은 타입에서 큰 타입으로 변환
    • 양수일 경우, 나머지 비트는 0으로 채운다.
    • 음수일 경우, 나머지 비트는 1으로 채운다. 형변환 후에도 부호 유지할 수 있도록 하기 위해.

실수형 형변환

  • float 에서 double 로 변환
    • 지수(E)는 float의 기저인 127을 뺀 후 double의 기저인 1023을 더해서 변환
    • 가수(M)는 float의 가수 23자리를 채우고 남은 자리를 0으로 채운다.
    • 가수의 변화를 눈여겨보자!
  • 실수형은 가수 저장시 버려지는 부분의 맨 처음 비트가 반올림된다.
  • 그러므로 같은 값을 저장하더라도, float를 double로 형변환했을 때 반올림 된 값이 있었다면 값이 같지 않다.

정수형과 실수형 형변환

  • 정수형을 실수형으로 변환
    1. 정수를 2진수로 변환
    2. 정규화
    3. 실수의 저장방식으로 저장
  • 실수형을 정수형으로 변환
    • 실수형의 소수점이하 값은 버려진다. 즉, 반올림이 발생하지 않는다.
    • 실수의 소수점을 버린고 남은 정수가 정수형의 저장범위를 넘는 경우 오버플로우 발생한다.

자동 형변환

  • 서로 다른 타입간의 대입/연산 할때 형변환으로 타입을 일치시키는 것이 원칙
  • 형변환 생략할 수 있는데, 컴파일러가 생략된 형번환을 자동으로 추가한다.
  • 형번환시 형변환을 생략하면 더 큰 수를 저장할 경우 에러가 발생한다.
  • 그러나 명시적 형변환시에는 의도로 간주하고 컴파일러는 에러를 발생시키지 않는다.
  • byte b = 1000; // 바이트의 범위 (-128~128). 자동 형변환 에러 발생. char ch = (char)1000; //명시적 형변환. 에러 미발생
  • 산술 변환 : 서로 다른 두 타입간의 연산에서는 두 타입 중 표현 범위가 더 넓은 타입으로 형변환하여 타입 일치시킨 다음에 연산 수행한다.

자동 형변환 규칙

  • 표현 범위가 좁은 타입에서 넓은 타입으로 형변환 된다. 값 손실이 없기 때문이다.
  • 자동 형변환이 가능한 방향
  • byte(1byte) → short(2byte) → int(4byte) → long(8byte) → float(4byte) → double(8byte) char(2byte) ↗
  • 실수형이 정수형보다 더 큰 표현 범위를 갖기 때문에 같은 byte를 사용하더라도 오른쪽에 위치한다.
  • short(음의 정수 포함)와 char는 같은 byte를 사용하지만, 서로 범위가 달라서 자동 형변환을 수행할 수 없다.

7 1차 및 2차 배열 선언하기

배열의 선언

  • 타입[] 배열이름

int[] array

배열 생성 방법

  • 선언된 배열은 new 키워드를 사용하여 실제 배열로 생성
  1. 배열이름 = new 타입[배열길이];
  2. 타입[] 배열이름 = new 타입[배열길이];

array = new int[10];

배열 선언과 동시에 생성 & 초기화

int[]grade=new int[3]; //길이 3인 int형 배열 선언 및 생성

    grade[0]=90; //인덱스를 이용한 배열의 초기화
    grade[1]=100;
    grade[2]=80;

배열의 초기화

  • 선언과 동시에 초기화 할 수 있다.
  • 괄호({})를 사용하여 초기값을 나열한 것을 초기화 블록(initialization block) 이라 한다.
  • 초기화 블록에 맞춰 자동으로 배열의 길이가 설정
  1. 타입[] 배열이름 = {배열요소1, 배열요소2, ...};
  2. 타입[] 배열이름 = new 타입[]{배열요소1, 배열요소2, ...};
int[]grade1={90,100,95}; //선언과 동시에 초기화
int[]grade2=new int[]{70,90,80}; //선언과 동시에 생성 초기화 

//이미 선언된 배열을 이 방법으로 초기화 하면 오류 발생 int grad1;
int[] grade3;
grade3={80,90,100};

8 타입 추론, var

  • 변수 선언시 타입 생략이 가능한 것으로, Java10 부터 타입 추론(type inference)이 도입되었다.
  • var str = "Hello, World!";
  • 컴파일 타임에 타입을 추론하므로 성능에 영향을 주지는 않는다.

제약사항

  1. 지역 변수에만 사용. 클래스 멤버변수로는 사용 불가.
  2. 초기화 필요. 타입 추론을 할 수 없기 때문에 컴파일 에러 발생.
  3. null로 초기화 할 수 없음. 이것도 마찬가지로 타입 추론이 불가능 하기 때문에 컴파일 에러 발생.
  4. 배열에 사용 불가
  5. 람다에 사용 불가

참고자료

'Java관련 > Java' 카테고리의 다른 글

Java 상속, 오버라이딩, 다이나믹 메소드 디스패치  (0) 2022.08.29
JVM과 자바 실행 과정 알아보기  (2) 2022.08.07
NoSuchElementException  (0) 2022.04.16
Objects.requireNonNull() - java.util.Objects  (0) 2022.04.16
static  (0) 2022.04.13

댓글