
기본형과 참조형에 대해 간략히 정리해 본 글. 겹치는 내용이 많을것이다
= 단 하나의 값만을 저장할 수 있는 메모리 상의 공간
int a = 5;
int b = 5;
System.out.println(a == b);
(X) System.out.println(a.equals(b));
위의 출력이 true로 나올 수 있는 이유는 a와 b가 가리키고 있는 주솟값이 같기 때문에! (같은 값 5를 저장하는 메모리 상의 공간을 가리키고 있기 때문에)
** equals는 객체끼리 두 값이 리터럴 하게 같은지 확인해주는 함수이기 때문에 기본형에선 쓸 수 없음!
보통은
int a = 10;
int b;
b = 5;
이렇게 두가지의 경우로 변수의 선언과 함께 초기화 한다.
** 지역변수는 무조건 초기화를 해야 하지만, 클래스변수와 인스턴스변수는 초기화를 생략할 수 있다.
(왜냐면 각 타입의 기본값으로 초기화 할 수 있기 때문
ex. int[] arr = new int[10] => 값이 0으로 초기화됨)
기본적인 설명은 위의 포스팅을 참조하면 된다.
변수의 타입을 알아야 하는 이유: 타입에 따른 값의 종류와 범위가 달라지는데, 이를 변수 선언시 저장할 값을 고려해서 넣어줘야 효율적이기 때문!
참조변수
Student s1 = null;
Student s2 = new Student();
//아래의 경우처럼 참조변수는 null or 주소값을 갖는다.
//여기서 객체를 생성하는 연산자 new가 사용됨으로써 새로운 객체의 주소를 생성한다.
//대입연산자 '='에 의해서 s2에 주소값이 저장됨
=> 참조형 변수는 기본형 변수들과 다르게 어떤 객체의 주소값을 저장할 것인가에 따라 구분되기 때문에, 자료형 대신 타입이라는 용어를 사용한다!
(자료형 ( 타입 -> 따라서 굳이 구분할 필요는 없긴 함,,)
위에서 정리한 것 처럼 총 8개의 자료형이 있다.

위의 그림은 기본형의 크기인데 이 크기에 따라 저장 가능한 값의 범위가 달라진다. 이때 정수형 4가지는 음의 값도 갖는다.
(ex. char -> 2byte -> 16bit -> 0~2^16-1까지)
char은 문자를 내부적으로 정수 코드로 저장한다.
char first = 'A';
char first2 = '\u0041';
//이렇게 두개가 같은 말, 아래는 A를 16진수로 바꿨을 때 41
int code = 65;
char c = (char) code;
System.out.println(c) // casting(형변환)되어 A가 출력됨!
(유니코드(국제적인 코드 규약)를 사용하므로 2byte)
**여기서 유니코드는 한글, 한자, 일어등의 문자가 1byte로 표현이 불가하기 때문에 탄생하여 2byte로 문자를 표현함
이때 char형 변수는 한 문자밖에 저장이 안되기 때문에 String클래스를 사용해서 여러 문자를 저장한다.
기본형, 참조형 구분 없이 문자열과 덧셈연산을 수행하면 그 결과는 문자열!
//example
String a = 7+7+""; //출력 14
String b = 7+""; //출력 7
*** 피연산자: 연산의 대상이 되는 값
**** JVM의 스택 영역(push, pop만 이뤄짐)에서 스택은 하나의 메서드가 실행될 때마다 스택 프레임이 생성되는데, 스택 프레임은 지역 변수 배열, 피연산자 스택, 실행 중인 메서드가 속한 클래스의 런타임 상수 풀에 대한 참조를 갖는다.
풀(pool) = 필요할 때마다 객체를 생성하고 파괴하는 대신, 사용 준비된 상태로 초기화된 개체 집합
런타임 상수 풀 = constant pool 테이블에 있는 class나 interface별 런타임 표현 (JVM의 static 영역에서 생성)
아래는 런타임 상수 풀이 갖는 상수
*** 여기서 피연산자 스택은 메서드의 실제 작업 공간으로 컴파일 시에 그 크기가 결정된다 (어떤 변수가 들어올지 모르니까).
l을 붙여줘야 한다** 리터럴 = 그 자체로 데이터 (ex. "A", 'a', 1)
(상수와 비슷한 의미로 받아들여질 수 있지만, 상수는 한번 저장되면 변경할 수 없는 저장공간이기 때문에 다르다!!)
//차례대로 부호+지수+가수
float = 1+8+23 = 32bit = 4byte
double = 1+11+52 = 64bit = 8byte
float num = 0.1f호구마가 정리해본 캐스팅
(다만 이 포스팅은 중점적으로 클래스 사이(상속 관계)에서의 캐스팅을 많이 다루고 있음)
보통은 같은 타입의 피연산자끼리 연산이 이뤄지나, 부득이 하게 다른 타입의 피연산자가 연산을 해야할 때 형변환이 일어나야 하기 때문에 사용한다.
** 그러나 기본형은 기본형끼리, 참조형은 참조형끼리만 형변환이 가능하다. (현재는 오토박싱 기능이 생겨 Object나 Wrapper 클래스를 활용해 기본형이 참조형으로 형변환이 가능해짐)
ex. Wrapper 클래스
Integer b = 1; int a = b.intValue()
ex. 형변환 예시
int score = (int) 95.4 // 95점
작은 범위 타입 -> 큰 범위 타입으로의 형변환은 생략할 수 있다.int a = 1;
long b = a;
int c = 1;
byte d = (byte) c; //요런식으로 캐스트 연산자를 꼭 써주어야 함
int i = 100;
long l = 100L;
final float PI = 3.14f;
System.out.println('A'+'B') // 65+66
System.out.println('1'+2) // 49+2
System.out.println('1'+'2') //49+50
System.out.println(true+null) //오류(boolean형은 연산 불가)
위에서 설명한 것처럼 키워드는 의미가 약속되어 있어야 하므로
if 제외한 True, Null, Class, System 모두 아님
** True가 아니라 true였다면 키워드
a. $ystem
기호 $, _는 특이하게 허용됨
b. $MAX_NUM
a. byte b = 256
byte의 범위는 -127~128임..
b. char c = ''
char은 무조건 글자가 있는 상태로 초기화 돼야 함
c. public static void main(String[] arv)
e. static public void main(String[] args)
=> 인자 메서드의 이름은 아무거나 써도 되며,
static과 public은 순서를 바꿔두 됨!
** 메서드 이름이 main인 이유도 JVM(안에 명시된 메서드 이름이 main임), void인 이유도 JVM(아무것도 리턴하지 않기 위함)
f. String - ""
String도 참조형이기 때문에 기본값은 null임
자바의 정석, 2nd Edition
https://velog.io/@kwak0568/JVM%EC%9D%98-%EC%9D%B4%ED%95%B4
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.5