자바 데이터 타입, 변수 그리고 배열
2주차과제 : 자바 데이터 타입, 변수 그리고 배열
목표
자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.
학습할 것
- 프리미티브 타입 종류와 값의 범위 그리고 기본 값
- 프리미티브 타입과 레퍼런스 타입
- 리터럴
- 변수 선언 및 초기화하는 방법
- 변수의 스코프와 라이프타임
- 타입 변환, 캐스팅 그리고 타입 프로모션
- 1차 및 2차 배열 선언하기
-
타입 추론, var
- 프리미티브 타입 종류와 값의 범위 그리고 기본 값
Primitive Type
이름 | 크기 | 값 범위 | 기본 값 | 비고 |
---|---|---|---|---|
byte | 1byte | -128 ~ 127 | 0 | |
short | 2bytes | -32,768 ~ 32,767 | 0 | |
signed int | 4bytes | $-2^{31}$ ~ $2^{31}-1$ | 0 | |
unsigned int | 4bytes | 0 ~ $2^{32}-1$ | 0 | java 8 이상부터 가능 |
signed long | 8bytes | $-2^{63}$ ~ $2^{63}-1$ | 0L | |
unsigned long | 8bytes | 0 ~ $2^{64}-1$ | 0L | java 8 이상부터 가능 |
float | 4bytes | single-precision 32-bit | 0.0f | |
double | 8bytes | double-precision 64-bit | 0.0d | |
boolean | 1bit | true / false | false | |
char | 2bytes | ‘\u0000’ ~ ‘\uffff’ | ‘\u0000’ | 하나의 문자만 저장할 수 있다. |
Signed 와 Unsigned 의 차이
- Signed : 부호를 가지는 값(양수, 음수의 구별 OK)
- Unsigned : 부호를 가지지 않는 값 (오직 양수 OK) ex ) unsigned int의 양수 범위 값이 signed int의 양수 범위 값보다 범위 표현이 넓다.( $2^{31}-1$ < $2^{32}-1$)
프리미티브 타입과 레퍼런스 타입
- Primitive type
- byte, short, int, long, float, double, boolean, char
- not object
- 값 저장
- Reference type
- class, interface, enum, array, String type
- 주소 저장
리터럴
- 리터럴이란 프로그램에서 직접 표현한 값을 의미한다.
- 고정된 값을 갖는 소스코드 표현 형태
-
종류로는 정수, 실수, 문자, 논리, 문자열 리터럴이 있다.
boolean result = true; char capitalC = 'C'; byte b = 100; short s = 10000; int i = 100000;
- Integer Literals
- long 타입은 L 로 끝나거나 I 로 끝나는 값
- 그외 나머지 숫자는 int
int a = 15; //10진수 리터럴 15 int b = 015; //0으로 시작하면 8진수, 13 int c = 0x15; //0x로 시작하면 16진수, 15 int d = 0b0101; //0b로 시작하면 2진수, 5
- 16진수 : 0x 로 시작
- 2진수 : 0b 로 시작
- Floating-Point Literals
- float 타입은 F로 끝나거나 f로 끝나는 값
- 그 외 나머지는 double (optional, D 혹은 d 로 끝나는 값)
float h = 0.1234f; //float는 f를 꼭 붙여줘야한다. double i = .1234D; //double은 생략가능
-
Character and String Literals
char a = 'H'; char b = "한"; char c = \uae00;(유니코드값)
- 문자 리터럴은 단일 인용부호(’’)로 문자를 표현한다.
- Unicode character
- special escape character
- \b : backspace
- \t : tab
- \n : new line
- \f : form feed
- \r : carriage return
- " : double quote
- ' : single quote
- \ : backslash
- 문자열 리터럴
- 문자열은 기본타입이 아니며, 더블 쿼터(””)로 문자열을 표현한다.
String literal = "JAVA"
변수 선언 및 초기화하는 방법
- 자바에서 변수를 사용하기 위해서는 변수를 선언해야 한다. 변수를 선언하는 이유는 값을 저장하는 공간을 확보하겠다는 이야기이다. 정확히는 컴퓨터가 가진 메모리를 사용하겠다고 미리 컴퓨터에게 말하는 것이다.
-
변수는 변수를 선언한 후 값을 할당해주어야만 사용할 수 있다. 경우에 따라 초기화를 하지 않고도 사용할 수 있지만, 기본적으로는 변수는 선언과 초기화가 이루어져야 사용할 수 있다.
class A { public int a; } class Hello { public static void main(String[] args) { String message1; // 변수 선언 message1 = "Hello World"; // 변수 초기화 String message2 = "Hello World"; // 변수 선언 및 초기화 int value = 10; // primitive type variable declaration and initialization A a = new A(); // reference type object declaration and initialization } }
변수의 스코프와 라이프타임
-
예시로 변수를 선언해보자
-
이 변수의 사용 범위는 어디까지일까? 이 변수의 사용 범위는 선언된 클래스의 중괄호 내에서 사용가능하다. 이 범위를 우리는 ‘스코프’라고 부른다.
- Class 안에 var1이란 변수가 선언됬으면 var1의 스코프는 클래스 전체에서 사용가능하다. 즉 foo() 메소드 안에도 들어갈 수 있다.
-
하지만 var2의 스코프는 foo() 안의 초록색 칸에서만 사용이 한정되어있다.
- 이렇게 if 문안에서 사용한 var3도 if문의 스코프 안에서만 활동할 수 있다.
- 생명주기(life Cycle)
- 모든 변수는 생명주기를 가진다. 생명주기란, 변수가 생성되고 죽는것을 말한다.
- 클래스 내에서 선언하는 변수를 인스턴스 변수
- 메소드 내에서 선언하는 변수를 지역변수라고 한다.
- member variable scope
public
modifier: 상속받은 모든 클래스에서 사용 가능private
modifier: 자기 클래스에서만 사용 가능
- 인스턴스 변수는 객체가 생성될 때, 변수가 생성된다. 즉, 현재 Test 클래스를 static main 메소드나 다른 클래스에서 인스턴스를 생성할때 생성이된다.
- Garbage Collector 에 의해 참조되지 않는 객체는 제거 대상이 됨 이때, 인스턴스 변수도 같이 소멸된다.
- 매개 변수는 예를 들어 foo() 메소드가 호출될 때, var3가 생성되고 foo() 메소드의 종료시점에 소멸된다.
- 클래스 변수인 정적변수는 클래스가 처음 호출되면서 생성, 자바 어플리케이션이 종료되면 소멸된다.
타입 변환, 캐스팅 그리고 타입 프로모션
- 캐스팅 → 명시적 형 변환, 강제 형 변환
- 프로모션 → 묵시적 형 변환, 암시적 형 변환, 자동 형 변환
- 자동 형 변환
- 경우에 따라 편의상의 이유로 형 변환을 생략할 수 있다. 그렇다고 해서 이루어지지 않는 것은 아니다.
- 컴파일러가 생략된 형 변환을 자동적으로 추가한다.
- ref) https://antstudy.tistory.com/242 형 변환 방법
- Casting → 리터럴의 타입을 다른 타입으로 변환하는 것
- Primitive type
- Widening type cast : 더 넓은 타입으로의 형 변환
- ex. int to long, byte to short
int value = 88; long value2 = value;
- Narrow type cast : 더 좁은 타입으로의 형 변환
- 값이 손실될 수 있음
- ex. long to int, short to byte
long value = 88; long value2 = value;
- Widening type cast : 더 넓은 타입으로의 형 변환
- Reference type
- 상속 관계에서만 가능
- Upcast : subcalss → superclass
- 모든 subclass는 superclass 의 컨텐츠를 가지고 있으므로 superclass 로의 casting이 가능함
- Downcast : superclass → subclass
- 모든 superclass는 subclass의 컨텐츠를 가지고 있지 않을 수도 있다. 그러므로 오류 발생 가능성이 크다.
1차 및 2차 배열 선언하기
class ArrayExample {
public static void main(String[] args) {
//1차원 배열
int[] oneDimensionArrayEx1 = {1, 2, 3, 4, 5};
int[] oneDimensionArrayEx2;
oneDimensionArrayEx2 = new int[5];
//2차원 배열
int[][] twoDimensionArrayEx1 = {{1,2},{3,4}};
int[][] twoDimensionArrayEx2;
twoDimensionArrayEx2 = new int[2][2];
}
}
- 1차원 배열
- oneDimmensionArrayEx1 은 Runtime Stack 영역의 힙 영역 주소값을 가짐
-
Heap 영역에 int 타입 크기의 요소 5개를 할당하여 사용됨
- 2차원 배열
- Runtime Stack 영역의 twoDimensionArrayEx1 은 2개의 요소크기 (2개 요소에 주소값을 가지고 있음) 를 가진 힙 영역 주소값을 가짐
-
힙 영역에는 실제 값이 들어있는 요소들과 주소값이 들어있는 요소들로 존재하게 됨
타입 추론, var
- 10버전 이상부터 type inference(타입 추론) 기능이 추가됨
- 타입 추론은 말 그대로 변수의 타입을 명시적으로 적어주지 않고도, 컴파일러가 알아서 이 변수의 타입을 대입된 리터럴로 추론하는 것이다.
- 대표적인 타입추론 언어는 자바스크립트, 코틀린, 스위프트 등이 있다.
public static void main(String[] args) {
String str = "Hello World";
} // 지역변수 선언 시 명시적인 타입을 적고, 선언
public static void main(String[] args) {
var str2 = "Hello type inference";
if(str2 instanceof String {
System.out.println("str2 변수의 타입은 String 입니다.");
}
} // str2 변수의 타입을 따로 명시X, 컴파일 시점에 컴파일러가 오른쪽에 있는 초기화 값 리터럴로 타입을 추론한다.
- var 라는 type keyword 를 사용하여 실제 타입을 추론
var url = new URL("http://www.naver.com") // var is URL type
var list = new ArrayList<String>(); // var is ArrayList<String> type
- var의 잘못된 사용법
- var 는 초기화없이 사용할 수 없다.
- var 타입의 변수에는 null 값이 들어갈 수 없다.
- var 타입은 로컬 변수에만 선언이 가능하다.
- Lambda Expression에는 명시적인 타입을 지정해줘야 한다.
-
배열을 선언할 때, var 대신 타입을 명시해줘야 한다.
~~var~~ i; // var 타입은 초기화 값을 선언부에 명시해줘야 한다. ~~var~~ i = null; //var 타입의 초기화 값은 'null'이 될 수 없다. private ~~var~~ i = "No member variable"; // 멤버 변수에 사용가능X ~~var~~ p :<lambda expression> = (String s) -> System.out.println("s = " + s); var arr :null = ~~{1,2,3}~~; //배열 선언할 떄 타입을 명시해줘야한다.
//var의 람다 익스프레션에서의 장점 Consumer<String> testFoo = s -> System.out.println("s = " + s); Consumer<String> testFoo = (var s)-> System.out.println("s = " + s); //변수 앞에 var를 넣을 수 있다. why? Consumer<String> testFoo = (@Nonnull var s)-> System.out.println("s = " + s); //키워드 앞에만 사용할 수 있는 어노테이션을 사용 가능하다는 장점
Reference 📝
https://www.notion.so/2-38b5d67c7f5a48238529bb8f1617ea0d
https://mine-it-record.tistory.com/100
https://7942yongdae.tistory.com/22
Leave a comment