작년 백기선님의 자바 스터디를 참여했던 포스팅에서 약간 수정하여 포스팅중입니다.
(추후 작성할 포스팅에 보조 설명 링크를 첨부하기 위해)
지금은 끝났지만 목차는 남아있기 때문에 자바를 공부를 하시는 분들은 깃헙 이슈에서 목차를 확인할 수 있습니다.
https://github.com/whiteship/live-study
Primitive type 종류와 값의 범위 그리고 기본 값
The Java programming language is statically-typed, which means that all variables must first be declared before they can be used. This involves stating the variable's type and name, as you've already seen
(Java 프로그래밍 언어는 정적으로 형식화되어 있으므로 모든 변수를 사용하기 전에 먼저 선언해야 합니다. 여기에는 변수의 유형과 이름을 지정하는 것이 포함됩니다.)
Java 프로그래밍 언어에서 지원하는 8가지 기본 데이터 유형이 있다.
byte(정수형)
|
short(정수형) :
|
int(정수형) :
|
long(정수형) :
|
float(실수형) :
|
double(실수형) :
|
boolean(논리형) :
|
char(문자형)
|
비트(바이트)마다 범위가 다른 이유?
비트마다 표현할 수 있는 범위가 다르기 때문이다. 1비트는 0, 1 총 2개의 숫자를 나태낼 수 있다. 2비트는 00, 01, 10, 11 총 4개의 숫자를 나타낼 수 있다.
java의 byte를 예로 들면 1바이트이므로 8개의 비트가 있다.
첫 번째는 양수인지 음수인지 판별하기 때문에 숫자는 총 7개의 비트로 숫자를 표현하기 때문에 -27~ 27-1이라는 범위가 나온다. 양수 범위에 -1을 한 이유는 0도 양수에 포함되어 있기 때문에 꼭 1을 빼줘야 한다.
부동 소수점
부동소수점에 대한 자세한 메커니즘은 IEEE 754 부동소수점을 검색하면 나온다.
여기서 짚고 넘어갈 부분은 부동소수점은 오차가 존재한다는 것이다.
public static void main(String[] args) {
double number = 0d;
for (int i = 0; i < 10; i++) {
number += 0.1;
}
System.out.println(number);
// 결과 : 0.9999999999999999
}
10진수의 소수를 2진수로 정확하게 만들 수 없어서 최대한 근사치를 반환하게 된다. 돈을 계산하거나 정확한 계산이 필요할 때는 float, double이 아닌 BigDecimal을 사용하면 된다.
public static void main(String[] args) {
BigDecimal number = BigDecimal.ZERO;
for (int i = 0; i < 10; i++) {
number = number.add(BigDecimal.valueOf(0.1d));
}
System.out.println(number);
// 결과: 1.0
}
primitive 타입과 reference 타입
자바에는 기본형 타입(Primitive type)과 참조형 타입(Reference type)이 있다.
기본형 타입은 위의 설명처럼 기본값을 가지고 있기 때문에 null이 존재하지 않는다. 그리고 스텍메모리에 저장된다.
레퍼런스 타입은 기본값이 null이고 힙 메모리 영역에 저장된다. 기본형 타입을 제외한 모든 타입이 레퍼런스 타입이라 생각하면 된다. Object에서 시작된 모든 클래스들이 레퍼런스 타입이다. 이름이 참 조형인 이유가 힙 메모리에 있는 주소를 참조해오기 때문에 참조형 타입이라고 부른다. 그래서 다른 곳에서 변경이 일어나면 주소에 저장되기 때문에 변경된 값을 가져올 수 있다.
리터럴
리터럴은 문자 그 자체를 의미한다. 데이터 타입을 더 명확하게 하기 위해서 사용한다.
- 정수 리터럴
- long 타입은 뒤에 L 혹은 l로 끝낸다. (l은 1과 헷갈릴 수 있기에 L을 사용한다.)
- 나머지는 int
- 0으로 시작하면 8진수
- 0x로 시작하면 16진
- 0b로 시작하면 2진수
int numebr = 10_000 // 7버전 이상에서 이런 표현도 가능하다
- 실수 리터럴
- float 타입은 F 혹은 f로 끝낸다.(보통 f로 사용하는 것 같다.
- double 타입은 D 혹은 d로 끝낸다.(마찬가지로 대부분 소문자를 사용하는 것 같다.)
- 문자 리터럴
- 유니코드 문자를 표현할 때는 '\\u'를 이용한다.
- 단일 인용부호 (' ') 로 정상적인 문자 하나 표현 ex) 'A'
- 특수문자 리터럴
- '\\b' : 백스페이스
- '\\t' : 탭
- '\\n' : 다음 줄로 넘어감
- '\\f' : 폼 피드
- '\\r' : 캐리지 리턴
- '\\"' : 이중 인용부호
- '\\'' : 단일 인용부호
- '\\\\' : 백슬래시
변수 선언 및 초기화하는 방법
public static void main(String[] args) {
// 타입 변수명
int number;
}
초기화하는 방법은 선언과 동시에 초기화를 할 수 있고 선언을 하고 초기화할 수 있다.
public static void main(String[] args) {
// 선언과 동시에 초기화
int number = 10;
// 선언 후 초기화
int number2; // 아직까지는 number2 = 0;
number2 = 10; // 이제 number2는 10
}
변수의 스코프와 라이프타임
변수는 선언 위치에 따라 멤버 변수와 지역 변수로 나뉜다. 멤버 변수에는 클래스 변수와 인스턴스 변수가 있다. 예제를 보면 쉽게 이해할 수 있다.
public class Test {
// 클래스 변수
static int NUMBER = 10;
// 인스턴스 변수
int number = 10;
public void testMethod() {
// 지역변수
int localNumber = 10;
}
}
클래스 변수와 인스턴스 변수는 생성되는 시기가 다르다. 클래스 변수는 클래스가 메모리에 올라갔을 때 생성이 되고 인스턴스 변수는 인스턴스가 생성되었을 때 생성된다.
인스턴스 변수
- 각 인스턴스 별로 저장 공간이 있다.
- 인스턴스를 생성할 때 생성, 더 이상 참조되지 않으면 가비지 컬렉터에게 수집된다.
클래스 변수
- 같은 클래스의 모든 인스턴스들이 같은 값을 공유하는 변수
- 인스턴스 생성 없이 생성한다. (클래스가 메모리에 올라갈 때 생성되므로)
- 클래스가 로딩될 때 생성되고 프로그램이 종료될 때 소멸된다.
지역변수
- 메서드 내에 선언되며, 메서드의 종료와 함께 소멸된다.
- 조건문, 반복문의 블록{} 내에 선언된 지역변수는 블록을 벗어나면 소멸된다.
- 반드시 초기화를 해야 한다.
타입 변환, 캐스팅 그리고 타입 프로모션
자바에는 자동 타입 변환(묵시적)과 강제 타입 변환(명시적)이 있다.
자동 타입 변환은 말 그래도 자동으로 타입을 변환해준다. 단 변경하는 타입이 변경할 타입보다 작아야 한다.
Primitive type
public void testMethod() {
int number = 10;
long castingNumber = number; // 묵시적으로 형 변환이 일어난다.
int downCastingNumber = castingNumber; // 컴파일 에러가 난다.
}
public static void main(String[] args) {
long number = 10;
int result1 = (int) number;
System.out.println("result1 = " + result1);
//result1 = 10
long bigNumber = 100000000000000L;
int result2 = (int) bigNumber;
System.out.println("result2 = " + result2);
//result2 = 276447232 값이 손실된다.
}
Reference type
public class Test {
public static void main(String[] args) {
Person person = new Developer(); // 상위클래스 타입은 하위 클래스를 생성할 수 있다.
Developer developer1 = (Developer) person; // 하위 클래스가 상위 클래스로 변환할때는 변환할 형을 입력해야 한다.
}
}
class Developer extends Person {}
class Person {}
참고 : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
참고 : https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html
'개발 > Java' 카테고리의 다른 글
[Java] 제네릭 (2) | 2022.03.02 |
---|---|
[JUnit] @ParameterizedTest - @MethodSource 사용하기 (0) | 2022.02.27 |
[Java] package, import (2) | 2022.02.15 |
[JUnit] Parameterized Test - 테스트를 효율적으로 (1) | 2022.02.11 |
[Java] 리플렉션 (reflection) 개념 이해하기 (0) | 2022.01.29 |