Skip to content

Latest commit

 

History

History
302 lines (168 loc) · 10.5 KB

2주차.md

File metadata and controls

302 lines (168 loc) · 10.5 KB

2주차

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

기본형 타입 primitive type

실제 값을 저장하는 공간으로 스택 Stack 메모리에 저장된다.

기본값이 있기 때문에 NULL이 존재하지 않는다.

컴파일시점에서 담을 수 있는 크기를 벗어나면 컴파일 에러가 발생할 수도 있다.

타입 할당된메모리크기 기본값 데이터의 표현범위
논리형 boolean 1 byte false true, false
정수형 byte 1 byte 0 -128 ~ 127
short 2 바이트 0 -32768 ~ 32767
int 4 바이트 0 -2147483648 ~ 2147438647
long 8 바이트 0L -9223372036854775808 ~ 9223372036854775807
실수형 float 4 바이트 0.0F (3.4 X 10-38) ~ (3.4 X 1038) 의 근사값
double 8 바이트 0.0 (1.7 X 10-308) ~ (1.7 X 10308) 의 근사값
문자형 char 2 바이트 \u0000 0~65535

마크업다운 문법이 처음이라 -38승과 38승 -308승 308승을 제대로 표현하지 못했습니다..

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

레퍼런스 타입

기본형 타입을 제회한 타입

빈 객체를 의미하는 NULL이 존재한다

값이 저장되어 있는 곳의 주소값을 저장하는 공간으로 힙(Heap) 메모리에 저장된다.

타입 기본값 할당되는 메모리크기
배열 NULL 4 byte
열거 NULL 4 byte
클래스 NULL 4 byte
인터페이스 NULL 4 byte

3. 리터럴

리터럴은 데이터 그 자체를 뜻한다.

예를들어 int a = 1; 이라고 할때 리터럴은 1이 된다.

즉, 1과 같이 변하지 않는데이터boolean, char, double, long, int ...를 리터럴 이라고 부른다.

상수와 리터럴을 비교하면 이해가 쉬운데 int a = 1; 에서 int 앞에 final을 붙이게 되면 바꿀 수 없는 변수가 됩니다.

한번 메모리에 변수를 지정하고 그 변수에 값을 초기화하고 난 그 이후에는 값을 바꿀 수 없는 변수를 상수로 말한다.

다시 말해 변수나 상수는 메모리에 할당된 공간이라면 리터럴은 이 공간에 저장되는 값이다.

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

int a; //변수선언
int a=1; //초기

초기화란 선언한 객체에 최초로 값을 넣어주는 것

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

자바에서 말하는 스코프란 변수에 대한 접근과 변수가 존재할 수 있는 영역을 의미한다.

흔히 사용하는 if(a){} {}로 한 영역이 생성된다면 그 영역에 관한 스코프를 형성하게 된다.

변수의 경우에는 스코프에 따라서 3가지 형태로 나타낼수 있다.

  • 인스턴스(instance)

스코프 : 정적메소드를 제외하고 클래스 전체

라이프타임 : 객체가 생성되고 메모리에 할당되어있는 시간동안

  • 클래스(class)

스코프 : 클래스 전체

라이프타임: program이 종료될때 까지

  • 지역(local)

스코프 : 변수가 선언된 영역 내에

라이프타임 : 변수가 선언된 이후부터 영역을 벗어날때 까지

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

자바에서 타입변환으로는 자동타입변환(묵시적), 강제타입변환(명시적) 두가지가 있다.

  • 자동 타입 변환

프로그램 실행 도중 자동으로 타입 변환이 일어난다.

작은 크기를 가진 타입이 큰 크기를 가지는 타입에 저장될 때 발생한다.

크키별로 타입을 정리하면 다음과 같다.

byte(1) < short(2) < int(4) < long(8) < float(4) < double(8)

float 은 4바이트 크기인데 int와 long보다 큰 타입으로 표시한 이유는 표현할 수 있는 값의 범위가 float이 더 크기 때문이다.

자동 타입 변환이 발생되면 변환 이전의 값과 변환 이후의 값은 동일하다. 즉, 변환 이전의 값은 변환 이후에도 손실 없이 그대로 보존된다.

정수 타입이 실수 타입으로 변환하는 것은 무조건 자동타입 변환이 된다. 자동타입 변환에서 단 하나의 예외가 있는데 char은 2 byte의 크기를 가지지만,

char 의 범위는 0~65535이므로 음수가 될수 없다. 따라서 음수가 저장될 수 있는 byte 타입을 char 타입으로 자동 변환 시킬 수 없다.

  • 강제 타입 변환

큰 크기의 타입은 작은 크기의 타입으로 자동 타입 변환을 할 수 없다. 마치 큰 크릇의 물을 작은 그릇 안에 모두 넣을 수 없는 것과 동일하다.

하지만 큰 그릇을 작은 그릇 사이즈로 쪼개어서 한 조각만 작은 그릇에 넣는다면 가능하다. 즉, int 타입을 4개의 byte로 쪼갠다음, 끝에 있는 1 byte만 byte

타입 변수에 저장하는 것은 가능하다. 이를 강제 타입 변환 casting이라고 한다.

작은 크기 타입 = (작은크기타입) 큰 크기 타입

예를 하나들어서


int intValue = 103029770;
byte byteValue = (byte) intValue; //강제 타입 변환

int타입 intValue 변수는 4byte이므로 1byte 크기를 가지는 byte 타입 byteValue 변수에 저장할 수 없다. 그래서 강제적으로 (byte) 캐스팅 연산자를 사용해서

int타입 intValue를 1byte씩 쪼개고, 끝에 있는 1byte만 byteValue 변수에 저장한다. 끝 1byte만 byte 타입 변수에 담게 되므로 원래 int 값은 보존되지 않는다.

하지만 intValue가 10일경우에는 1byte에 10을 2진수로 충분히 표현할 수 있으므로 값이 그대로 유지된다.

강제 타입변환에서 주의할 점은 사용자로부터 입력받은 값을 변환할 때 값의 손실이 발생하면 안된다.

자바는 코드에서 데이터 값을 검사하기 위해 boolean 과 char타입을 제외하고 모든 기본 타입에 대해 최대값과 최소값을 상수로 제공한다.

예) byte 최대값 상수 : Byte.MAX_VALUE, 최소값 상수 : Byte.MIN_VALUE

또한 정수 타입을 실수 타입으로 변환할 때 정밀도 손실을 피해야 한다.

예를 들어

int num1 = 123456780;
int num2 = 123456780;

float num3 = num2; //해결책: double num3 = num2;
num2 = (int)num3;
int result = num1 - num2;

를 하면 결과는 0이 나올거라고 생각하지만 결과는 -4가 나온다 이는 float 타입은 부호(1비트) + 지수(8비트) + 가수(23비트)로 할당되어있기 때문이다.

이를 해결하기 위해서는 double 타입을 사용해야한다. double 타입은 부호(1비트) + 지수(11비트) + 가수(52비트) 이므로 int의 크기는 32비트 이고 즉,

double의 가수 > int 비트 크기 이므로 결과는 0이 나온다.

  • 연산식에서의 자동타입 변환

연산은 기본적으로 같은 타입의 피연산자 간에만 수행되기 때문에 서로 다른 타입의 피연산자가 있을 경우 두 피연산자 중 크기가 큰 타입으로 자동 변환된 후 연산을 수행한다.

예를 들어

int intValue = 10;
double doubleValue = 5.5;
double result = intValue + doubleValue; //결과는 15.5

만약 int 타입으로 연산을 해야한다면 double타입을 int타입으로 강제 변환하고 덧셈을 해야한다.

int intValue = 10;
double doubleValue = 5.5;
int result = intValue + (int)doubleValue; //결과는 15

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

변수는 한 개의 데이터만 저장할 수 있다. 따라서 저장해야 할 데이터의 수가 많아지면 그만큼 많은 변수가 필요하다.

예를들어 학생 30명의 성적을 저장하고 이에대한 평균값을 구해야한다면..?

int student1 = 80;
int student2 = 100;
int student3 = 90;
int student4 = 70;
int student5 = 50;
.
.
.
언제까지 복붙할거냐..

위와 같은 문제를 효율적으로 해결하기 위해 배열이 필요하다.

1차원 배열 선언
String array1[];
//String[] array1;

2차원 배열 선언
String array2[][];
//String[][] array2[][];

배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 된다. 참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화 될 수 있다.

배열 항목에 저장될 값의 목록이 있다면, 다음과 같이 간단하게 배열 객체를 만들 수 있다.

int intarray[] ={1,2,3,4,5,6,7}
//intarray는7개의 int가 들어가있다.
그럼 intarray[7]인가? x
배열은 0부터 시작하기 때문에 intarray[6]이 된다.

intarray[2] = 3 이나온다.

값의 목록으로 배열 객체를 생성할 때 주의할 점이 있는데, 배열 변수를 이미 선언한 후에 다른 실행문에서 중괄호를 사용한 배열 생성은 허용되지않는다.

타입[] 변수;
변수 = {값0, 값1, 값2, 값3, ...} //컴파일 에어

배열 변수를 미리 선언한 후, 값 목록들이 나중에 결정되는 상황이라면

변수 = new 타입[] {값0, 값1, 값2, 값3, ...};

로 나열해주면 된다.

값의 목록을 가지고 있지 않지만 , 향수 값들을 저장할 배열을 미리 만들고 싶다면 new 연산자로 다음과 같이 배열 객체를 생성시킬 수 있다.

타입[] 변수 = new 타입[길이];
int[] intarray = new int[5];

8. 타입 추론 , var

타입 추론이란 코드 작성 당시 타입이 정해지지 않았지만, 컴파일러가 그 타입을 유추하는 것

Java 10 부터 타입 추론을 지원하는 var 키워드가 추가되었다.

이 키워드는 local variable 이면서 선언과 동시에 initializer가 필수적으로 요구된다.

//java 9이하
String message = "data";
//java 10이상
var message = "the initialzer"

컴파일러는 오른쪽에 초기화 값을 제공되는 것을 통해 타입을 유추한다.

참고블로그 및 문헌

https://gbsb.tistory.com/6

https://www.learningjournal.guru/article/programming-in-java/scope-and-lifetime-of-a-variable/

이것이 자바다

https://velog.io/@bk_log/Java-%ED%83%80%EC%9E%85-%EC%B6%94%EB%A1%A0