목표
자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.
위의 사진은 구글 데이터센터의 내부 모습이다. 알파고가 돌아갔던 서버였다고도 한다. 정말 어마무시한 크기를 자랑하는 데이터센터이지만 이들도 데이터센터 효율성을 높이기 위해 어떤 노력을 기울였고, 결국 업계 평균 수치보다 50% 이상의 높은 에너지 효율성을 달성했다고 한다. 만약 같은 크기의 데이터센터에서 고작 Hello World만 찍는다면 얼마나 안타까운 일인가!?
자바에서도 데이터 타입마다 메모리 할당이 다르게 된다. 그렇기때문에 데이터 타입의 크기를 알고 내가 하고자 하는 일에 알맞는 데이터 타입을 사용하는 것은 자바를 떠나 모든 영역에서 중요한 일이다.
프리미티브 타입 종류와 값의 범위 그리고 기본 값
변수 타입 | 변수 종류 | 기본 값 | 크기 | 범위 |
boolean | true / false (논리 리터럴) | false | 1bit | N/A |
char | Unicode Character (문자) | \u0000 | 16bits | \u0000 ~ \uFFFF |
byte | Signed Integer (정수) | 0 | 8bits | -128 ~ 127 |
short | Signed Integer (정수) | 0 | 16bits | -32768 ~ 32767 |
int | Signed Integer (정수) | 0 | 32bits | -2147483648 ~ 2147483647 |
long | Signed Integer (정수) | 0 | 64bits | -9223372036854775808 ~ 9223372036854775807 |
float | IEEE 754 floating point (실수) | 0.0f | 32bits | 1.4E-45 ~ 3.4028235E38 |
double | IEEE 754 floating point (실수) | 0.0d | 64bits | 4.9E-324 ~ 1.7976931348623157E308 |
프리미티브 타입과 레퍼런스 타입
자바의 데이터 타입에는 크게 기본 타입과 참조 타입으로 분류된다. 두 타입의 차이는 저장되는 값이 무엇인가이다. 기본 타입은 선언된 변수에 실제 값을 가지지만, 참조타입은 선언된 변수에 메모리 주소가 값으로 들어간다.
기본 타입 (Primitive Type)
- 정수 (byte, short, int, long), 실수 (float, double), 문자 (char), 논리 리터럴 (boolean) 타입을 말한다.
참조 타입 (Reference Type)
- 객체의 주소(번지)를 참조하는 타입으로 배열, 열거, 클래스, 인터페이스 타입을 말한다.
리터럴
프로그램에서 직접 표현한 값 즉, 데이터 그 자체를 뜻 한다. 소스 코드의 고정된 값을 대표하는 용어이다.
변수 선언 및 초기화하는 방법
// 변수 선언
int price; int a,b,c,d,e;
Moon moon;
// 변수 초기화
price = 100;
moon = new Moon();
선언과 초기화
int age = 5;
Moon moon = new Moon();
kim kim = null;
변수의 스코프와 라이프타임
인스턴스 변수
클래스 내부와 모든 메소드 및 블록 외부에서 선언 된 변수는 인스턴스 변수이다. 인스턴스 변수의 일반적인 범위는 정적 메서드를 제외한 클래스 전체이다. 인스턴스 변수의 수명은 객체가 메모리에 남아있을 때까지이다.
클래스 변수
클래스 내부, 모든 블록 외부에서 선언되고 정적으로 표시된 변수를 클래스 변수라고 한다. 클래스 변수의 일반적인 범위는 클래스 전체에 있으며 클래스 변수의 수명은 프로그램이 끝날 때까지 또는 클래스가 메모리에로드되는 동안이다.
지역 변수
인스턴스 및 클래스 변수가 아닌 다른 모든 변수는 메서드의 매개 변수를 포함하여 지역 변수로 처리된다. 지역 변수의 범위는 선언 된 블록 내에 있으며 지역 변수의 수명은 컨트롤이 선언 된 블록을 떠날 때까지이다.
타입 변환, 캐스팅 그리고 타입 프로모션
유형 캐스팅은 한 기본 데이터 유형의 값을 다른 유형에 할당하는 것이다. Java에는 두 가지 유형의 캐스팅이 있습니다.
- 확대 주소 (자동) 작은 유형을 큰 유형의 크기로 변환
byte-> short-> char-> int-> long-> float->double - Narrowing Casting (수동)-큰 유형을 작은 유형의 크기로 전환
double-> float-> long-> int-> char-> short->byte
public class Main {
public static void main(String[] args) {
int myInt = 9;
double myDouble = myInt; // 확대 캐스팅
System.out.println(myDouble); // 9.0
double myDouble2 = 9.78;
int myInt2 = (int) myDouble2; // 수동 캐스팅
System.out.println(myInt2); // 9 => 0.78이란 값을 잃어버렸다.
}
}
1차 및 2차 배열 선언하기
배열을 선언할땐 인스턴스 변수 (참조 변수) 만 먼저 선언하여 크기와 값을 이후에 초기화 할 수 있고, 최초 선언시 크기와 값을 할당해주는 것도 가능하다. 너무 다양한 방법이 있지만 데이터 타입뒤에 []를 넣어주는것이 제일 좋다고 생각이 든다.
간단한 예시 몇 가지
// 1차원 배열
int[] arr = new int[5];
int[] arr; arr = {1,2,3,4,5};
// 2차원 배열
int[][] arr = new int[2][2];
int[][] arr = {{2,5},{3,4}};
타입 추론과 var 타입
타입추론
인터페이스에 정해진 제네릭 타입을 확장하는 컬렉션 제네릭에서 추론하여 자동 생성해주기 때문에 제네릭 타입을 명시해주지 않아도 된다.
다시 말하자면 타입 추론이란 코드 작성 당시 타입을 정해주지 않더라도 컴파일러가 그 타입을 유추하는 것이다.
// java version - 1.6 이전
List<String> list = new ArrayList<String>();
Map<String, Object> map = new HashMap<String, Object>();
// java version - 1.7
List<String> list = new ArrayList<>();
Map<String, Object> map = new HashMap<>();
// java version - 10 + LTS java version - 11
var list = new ArrayList<String>();
var map = new HashMap<String, Object>();
var stream = list.stream();
var
개발자가 종종 필요하지 않은 지역 변수 유형의 매니페스트 선언을 제거 할 수 있도록함으로써 정적 유형 안전성에 대한 Java의 노력을 유지하면서 Java 코드 작성과 관련된 의식을 줄임으로써 개발자 경험을 개선하고자합니다. 이 기능은 예를 들어 다음과 같은 선언을 허용합니다.
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
사용가능 범위
var numbers = List.of(1, 2, 3, 4, 5);
for (var number : numbers) {
System.out.println(number);
}
for (var i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
제한
* var 타입은 타입 추론시 다이아몬드 연산자 안에 타입을 넣지 않으면 Object로 추론한다.
* 주의해야할 점은 기존에 자바의 RHS(lamda, generics, diamond)에서 이미 타입 추론을 하고 있기 때문에, 해당 표현식의 LHS에 var 로 대입하면 추론이 실패될 수 있습니다.
References.
'공부 > 스터디할래? with.백기선' 카테고리의 다른 글
3주차 과제: 연산자 (0) | 2020.11.28 |
---|---|
1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가? (0) | 2020.11.14 |
댓글