목차

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

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

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



타입 종류



타입 범위



실수형의 정밀도



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

자료형은 크게 '기본형(Primitive Type)' 과 참조형(Reference Type)으로 나눌 수 있다.


좀 더 얘기하자면 기본형은 메모리영역의 스택영역에 실제 값들이 저장된다면, 참조형은 실제 인스턴스는 힙영역에 생성되있고, 그 영역의 주소를 스택영역에서 저장하고 있다고 보면 된다.

리터럴

💡 그 자체로 값을 의미하는 것 


🤔 인스턴스는 리터럴이 될 수 있을까?


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

변수 선언

변수를 사용하기위해서는 우선 변수를 선언해야 하며 아래 그림과 같이 선언합니다.


이렇게 변수를 선언하면, 메모리의 빈 공간에 '변수타입'에 알맞은 크기의 저장공간이 확보되고, 변수 이름을 붙혀서 이 이름을 통해 해당 저장공간을 사용할 수 있게 된다.

변수 초기화

💡 변수를 사용하기 전 처음으로 값을 저장하는 것

변수를 선언하면 메모리에 변수의 저장공간이 확보되어있지만, 여러 프로그램에 의해 공유되기 때문에 이 공간안에 어떠한 값이 저장되어있을지는 알 수 없다.

그렇기에 초기화(initialization)를 해줘야 한다.




💬지역변수는 사용하기 전 반드시 초기화 해야 한다.

그밖의 초기화의 종류

지역변수는 변수의 초기화로 충분하지만, 멤버변수의 초기화는 몇가지 방법이 더 있다.

1. 명시적 초기화(explicit initialization)

: 변수 선언과 동시에 초기화 하는 것을 명시적 초기화라 하는데, 위에서 소개한 변수의 초기화와 동일하며, 클래스 및 지역변수 어디서든 사용가능하며 여러 초기화 방법중 최우선적으로 고려한다.

2. 초기화 블럭(initialization block)

: 초기화 블럭은 클래스 초기화 블럭과 인스턴스 초기화 블럭으로 나뉜다.

class ExplicitInitialization {
  static {
	/*클래스 초기화 블럭 */
}
{
	/*인스턴스 초기화 블럭*/
}
}

3. 생성자(constructor)

: 생성자는 말 그대로 인스턴스 생성시에 생성자 함수 안에서 명시적 초기화가 이뤄진다.

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

스코프는 한글로 풀어보자면 범위이다. 즉, 변수의 스코프는 변수의 범위라는건데 이 범위는 키워드와 선언된 블럭위치에 따라서 달라진다.

선언위치에 따른 변수의 종류

class A {
  int instanceValue; //인스턴스 변수
  static int classValue;//클래스 변수(static, 공유 변수)
       
  void method(){
    int localValue = 0; //지역 변수
  }
}


클래스 내부에 선언되는 변수를 멤버변수라 한다. 여기서 static키워드가 붙은 변수를 클래스 변수, static 키워드가 없는 변수를 인스턴스 변수라 한다. 그리고 메서드 내부에 있는 localValue는 지역변수이다. 이 셋 모두의 범위와 생성시기는 다르다.

1. 변수의 종류와 특징


1) 인스턴스 변수(instance variable)


2) 클래스 변수(class variable)

class LottoTicket {
  public static final LOTTO_PRICE = 1000;
  ...
}
public static void main(String[] args) {
  //LottoPrice: 1000
  System.out.println("LottoPrice: "+ LottoTicket.LOTTO_PRICE);
}


3) 지역 변수(local variable)

public static void main(String[] args) {
  	  for (int i = 0; i < 10; i++) {
        System.out.println("i = " + i);
    }
    System.out.println("i = " + i);//Checked Exception 발생
}



초기화 시기와 순서(라이프타임)

1. 초기화 시점


⇒ 프로그램 실행도중 클래스에 대한 정보가 요구될 때 클래스는 메모리에 로딩된다.
(만약 이미 메모리에 로딩되어 있다면 또다시 로딩하지는 않는다.)

2. 초기화 순서


3. 예제

class InitTest {
  static int classValue = 1;
  int instanceValue = 1;
  
  static {
	  classValue = 2;
  }
  InitTest() {
	  instanceValue = 3;
  }
}



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

타입 변환

💡 변수 또는 상수의 타입을 다른 타입으로 변환하는 것

프로그램을 작성하다보면 서로 다른 타입간의 연산을 수행해야 하는 경우가 있다. 이럴 때 연산을 수행하기 전 서로의 타입을 일치시켜야하는데, 이렇게 변수나 리터럴의 타입을 다른 타입으로 변환하는 것을 형변환이라 한다.

형변환 방법

💡 (type)operand


double value = 123.456;
int score = (int)value;
System.out.println(value == 123.456); //true


자동 형변환

byte b = 10000; //에러 발생. byte의 범위는 -128~127이다.
byte c = (byte)10000; //명시적 형변환으로 에러가 발생하지 않는다.


자동 형변환 규칙

💡 기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환한다.


기본형의 자동 형변환의 방향

1차 및 2차 배열 선언하기

배열의 선언과 생성

1. 배열의 선언

2. 배열의 생성

타입[] 변수이름 = new 타입[길이];


1차원 배열의 선언 & 2차원 배열의 선언

1. 1차원 배열의 선언

int[] oneDimensionalArray = new int[5]{1, 2, 3, 4, 5};

메모리에 올라간 1차원 배열

2. 2차원 배열의 선언

int[][] twoDimensionalArray = new int[2][2]{{1, 2}, {3, 4}};

메모리에 올라간 2차원 배열

타입 추론, var

타입 추론

static <T> T pick(T a1, T a2) { return a2; }
public static void main(String[] args) {
  	  Serializable d = pick("d", new ArrayList<String());
}

타입추론과 Generic Methods

public class BoxDemo {
	  public static <U> void addBox(U u, java.util.List<Box<U>> boxes) {
			  Box<U> box = new Box<>();
			  box.set(u);
			  boxes.add(box);
	  }
}
public static <U> void outputBoxes(java.util.List<Box<U>> boxes) {
    int counter = 0;
    for (Box<U> box: boxes) {
      U boxContents = box.get();
      System.out.println("Box #" + counter + " contains [" +
             boxContents.toString() + "]");
      counter++;
    }
  }

  public static void main(String[] args) {
    java.util.ArrayList<Box<Integer>> listOfIntegerBoxes =
      new java.util.ArrayList<>();
    BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes); //---(1)
    BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);//---(2)
    BoxDemo.addBox(Integer.valueOf(30), listOfIntegerBoxes);
    BoxDemo.outputBoxes(listOfIntegerBoxes);
  }
}


(1) : addBox라는 generic 메소드를 호출할 때 <Integer> type witness와 함께 type parameter를 명시하여 사용할 수 있다.
(2) : Java 컴파일러가 메소드의 인자로부터 자동으로 Integer type임을 추론해주기 때문에 type witness를 생략할 수도 있다.

타입추론과 Generic 클래스의 인스턴스

List<String> myList1 = new ArrayList<String>();
List<String> myList2 = new ArrayList<>();


타입추론과 Generic 생성자

class MyClass<X> {
  <T> MyClass(T t) {
    // ...
  }
}

public static void main(String[] args) {
  MyClass<Integer> myInstance = new MyClass<Integer>("");
}


Java SE 7이전에는 컴파일러에서 실제 type argument를 작성해 타입 추론을 할 수 있었지만,
Java SE 7이후로 컴파일러는 the diamond(<>)를 사용하는 경우 다음과 같이 generic 클래스의 실제 type argument까지 추론이 가능하다.

MyClass<Integer> myInstance = new MyClass<>("");


Target Types

static <T> List<T> emptyList() { return new ArrayList<>(); }
List<String> listOne = Collections.emptyList();


List<String> listOne = Collections.<String>emptyList(); //불필요한 witness 


void processStringList(List<String> stringList) {
  	  //process stringList
}
public static void main(String[] args) {
	  processStringList(Colections.emptyList());
}
List<Object> cannot be converted to List<String> 
processStringList(Colections.<String>emptyList());


var

var list = new ArrayList<String>(); //infers ArrayList<String>
var stream = list.stream();//infers Stream<String>


Local Variable Type Inference 사용 조건

var 활용

1. 지역변수 선언

var numbers = Arrays.asList(1, 2, 3, 4, 5);

for (var i = 0; i < numbers.size(); i++) {
    System.out.println("numbers = " + numbers.get(i));
}


2. forEach

var numbers = Arrays.asList(1, 2, 3, 4, 5);

for (var number : numbers) {
    System.out.println(number);
}


3. Lambda (Java 11)

IntBinaryOperator plus10 = (@NonNull var one, @NonNull var two) -> one + two + 10;

Ref

https://github.com/whiteship/live-study/issues/2

https://blog.naver.com/hsm622/222144931396
https://www.notion.so/damho1104/2-38b5d67c7f5a48238529bb8f1617ea0d
https://velog.io/@jaden_94/2%EC%A3%BC%EC%B0%A8-%ED%95%AD%ED%95%B4%EC%9D%BC%EC%A7%80
https://github.com/kksb0831/Practice_project/blob/master/Java_Study_02.md
https://catsbi.oopy.io/6541026f-1e19-4117-8fef-aea145e4fc1b
https://www.notion.so/2-00ffb2aeb41d450aa446675b8a9e91d5
https://b-programmer.tistory.com/225
https://github.com/yeo311/java-study-with-whiteship/tree/main/week2
https://blog.naver.com/swoh1227/222149491648
https://catch-me-java.tistory.com/14
https://catch-me-java.tistory.com/15
https://catch-me-java.tistory.com/16
https://catch-me-java.tistory.com/17
https://catch-me-java.tistory.com/18
https://catch-me-java.tistory.com/19
https://catch-me-java.tistory.com/20
https://docs.google.com/presentation/d/1Ni0FMbVBSTxiOWHvp928quGT8sTjTG_ZuAWxaCFGT1E/edit?usp=sharing
https://github.com/league3236/startJava/blob/master/live_study/week2.md
https://github.com/Rebwon/TIL/blob/master/live-study/second.md
https://github.com/yeGenieee/java-live-study/blob/main/%5B2%5DJava%20Live%20Study.md
https://scshim.tistory.com/169
https://www.notion.so/2-4bc4a76a553d46b78d7ad1af6fa7df2b