자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법을 익힙니다.
false
\u0000
0
0
0.0F
0.0
float
의 정밀도는 7자리로 10진수로 7자리의 수를 오차없이 저장할 수 있다는 의미다. 그렇기에 사용할 변수의 값의 범위가 7자리를 넘는다면 정밀도를 고려해 double
타입을 사용해야 한다.
자료형은 크게 '기본형(Primitive Type)' 과 참조형(Reference Type)으로 나눌 수 있다.
Java.lang.Object
를 상속받을경우 참조형이 된다. 즉, 기본형을 제외하고는 참조형이라 생각해도 된다.
좀 더 얘기하자면 기본형은 메모리영역의 스택영역에 실제 값들이 저장된다면, 참조형은 실제 인스턴스는 힙영역에 생성되있고, 그 영역의 주소를 스택영역에서 저장하고 있다고 보면 된다.
💡 그 자체로 값을 의미하는 것
그림
에서 2020
이 리터럴이다.상수
의 다른 이름이라고 볼 수 있다.🤔 인스턴스는 리터럴이 될 수 있을까?
불변성(Imutable)
이 보장된다면 객체 리터럴이 될 수 있다.(불변 클래스(imutable class)
) 객체 리터럴
이 될 수 없다.Java.lang.String
이나 java.awt.Color
같은 클래스는 내용이 변해야 하는 상황이면 새로운 객체를 만들어 내용의 불변성이 보장되기에 객체 리터럴
이라 부른다.
변수를 사용하기위해서는 우선 변수를 선언해야 하며 아래 그림과 같이 선언합니다.
이렇게 변수를 선언하면, 메모리의 빈 공간에 '변수타입'에 알맞은 크기의 저장공간이 확보되고, 변수 이름을 붙혀서 이 이름을 통해 해당 저장공간을 사용할 수 있게 된다.
💡 변수를 사용하기 전 처음으로 값을 저장하는 것
변수를 선언하면 메모리에 변수의 저장공간이 확보되어있지만, 여러 프로그램에 의해 공유되기 때문에 이 공간안에 어떠한 값이 저장되어있을지는 알 수 없다.
그렇기에 초기화(initialization)
를 해줘야 한다.
=
을 사용한다. 위 그림을 보면 year
라는 int
변수타입과 year
라는 변수 이름을 가진 변수에게 2020
이라는 값을 대입한다.
💬지역변수는 사용하기 전 반드시 초기화 해야 한다.
지역변수는 변수의 초기화로 충분하지만, 멤버변수의 초기화는 몇가지 방법이 더 있다.
: 변수 선언과 동시에 초기화 하는 것을 명시적 초기화라 하는데, 위에서 소개한 변수의 초기화와 동일하며, 클래스 및 지역변수 어디서든 사용가능하며 여러 초기화 방법중 최우선적으로 고려한다.
: 초기화 블럭은 클래스 초기화 블럭과 인스턴스 초기화 블럭으로 나뉜다.
class ExplicitInitialization { static { /*클래스 초기화 블럭 */ } { /*인스턴스 초기화 블럭*/ } }
클래스 초기화 블럭
: 클래스변수의 복잡한 초기화에 사용. 블럭내에서는 로직도 추가할 수 있기 때문에 명시적 초기화만으로 부족할 때 사용한다.인스턴스 초기화 블럭
: 인스턴스 변수의 복잡한 초기화에 사용. 모든 생성자가 공통으로 수행해야 하는 로직이 있을 때 사용한다.: 생성자는 말 그대로 인스턴스 생성시에 생성자 함수 안에서 명시적 초기화가 이뤄진다.
스코프는 한글로 풀어보자면 범위이다. 즉, 변수의 스코프는 변수의 범위라는건데 이 범위는 키워드와 선언된 블럭위치에 따라서 달라진다.
class A { int instanceValue; //인스턴스 변수 static int classValue;//클래스 변수(static, 공유 변수) void method(){ int localValue = 0; //지역 변수 } }
클래스 내부에 선언되는 변수를 멤버변수라 한다. 여기서 static키워드가 붙은 변수를 클래스 변수, static 키워드가 없는 변수를 인스턴스 변수라 한다. 그리고 메서드 내부에 있는 localValue는 지역변수이다. 이 셋 모두의 범위와 생성시기는 다르다.
1) 인스턴스 변수(instance variable)
2) 클래스 변수(class variable)
static
키워드를 붙힐 경우 클래스 변수가 되며 한 클래스의 모든 인스턴스가 값을 공유한다.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 발생 }
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
boolean
을 제외한 나머지 타입은 서로 형변환이 가능하다.
byte b = 10000; //에러 발생. byte의 범위는 -128~127이다. byte c = (byte)10000; //명시적 형변환으로 에러가 발생하지 않는다.
💡 기존의 값을 최대한 보존할 수 있는 타입으로 자동 형변환한다.
1. 배열의 선언
[]
)를 붙히면 된다. 2. 배열의 생성
타입[] 변수이름 = new 타입[길이];
new
연산자를 사용해 배열의 타입과 길이를 지정하면 메모리에 해당 길이만큼 영역을 확보한다.
[]
)의 갯수 차이이다. 대괄호가 1개이면 1차원, 2개이면 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차원 배열
new int[행][열]
로 본다고 할 때 위에 코드인 twoDimensionalArray
는 2행 2열짜리 2차원 배열인 것이다.Type Inference
이라 한다. static <T> T pick(T a1, T a2) { return a2; } public static void main(String[] args) { Serializable d = pick("d", new ArrayList<String()); }
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를 생략할 수도 있다.
List<String> myList1 = new ArrayList<String>(); List<String> myList2 = new ArrayList<>();
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<>("");
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 list = new ArrayList<String>(); //infers ArrayList<String> var stream = list.stream();//infers Stream<String>
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;
참고
: 비어있는 type witness를 사용하면 Object로 추론한다.
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