JAVA_#1_1
오늘 배운 내용을 복습하면서 작성하는 TIL
변수
단 하나의 값을 저장할 수 있는 메모리 공간을 의미한다.
메모리 공간은 각각이 구분될 수 있도록 '메모리 주소'를 가지고 있다.
메모리 주소 참고 : == : 비교하고자 하는 두 피연산자의 주소값을 비교한다.
위 이미지 처럼 저장되는 값의 종류에 따라, 변수의 메모리 공간 크기가 결정된다.
변수 생성 규칙
- 대소문자가 구분되며 길이에 제한이 없음
- 예약어(ex->true) 사용 불가
- 숫자로 시작 불가
- 특수문자 _ 와 $ 만 허용
변수의 여러가지 형태
Camel case
varTest
Snake case
var_test
Pascal case (Java 에는 클래스명만 대문자로 시작하자는 암묵적인 규칙이 있어서 추천 X)
VarTest
Kebab case (Java 에서는 변수명에 - 기호 사용 불가)
var-test
변수의 초기화
- 변수에 값을 저장하는 방법 : 변수타입 변수이름 = 값;
- int age; age = 23; or int age = 23; or int age = 23, num = 32768;
- 초기화 : 변수에 처음으로 값을 저장하는 것을 의미합니다.
class Variable1_3 {
public static void main(String[] args) {
int year, age = 23;
year = age + 2000;
System.out.println("year = " + year); // 2023
// 변수의 값을 읽어오는 과정
// year = age + 2000;
// year = 23 + 2000;
// year = 2023;
age = age + 1;
System.out.println("age = " + age); // 24
System.out.println("year = " + year); // 2023
// 변수의 값을 읽어오는 과정
// age = age + 1;
// age = 23 + 1;
// age = 24;
// 프로그램은 순차적으로 코드가 실행되기 때문에
// 여기서 age의 값이 바뀌었다고 year에 영향을 주지 않는다.
}
}
*프로그램은 순차적으로 코드가 실행된다.
상수
한 번만 값이 저장 가능한 변수
선언 방법 : final 변수타입 변수이름;
를 통해 값을 하나만 지정한다.
리터럴
리터럴 그 자체로 값을 의미하는 것
기존의 상수와 같은 의미입니다.
하지만 Java에서 상수를 '한 번만 값이 저장 가능한 변수' 라는 의미로 사용하기 때문에
이를 구별하기 위해 사용하는 용어입니다.
리터럴의 접두사와 접미사
정수형의 int은 기본형이기 때문에 접미사를 붙이지 않고,
- byte, short 타입의 변수도 접미사가 존재하지 않는다.
- long 타입은 구분을 위해 100L 처럼 리터럴 마지막에 접미사로 L을 붙입니다.
*byte, short 타입은 연산에 이용하기보다는 저장 목적인 경우가 많아 Java 의 내장 변환모듈이 자동으로 형 변환시켜 줍니다.
실수형의 double은 기본형이기 때문에 접미사를 붙이지 않고,
- float의 리터럴에는 f가 붙습니다.
*실수형은 2개 밖에 존재하지 않기 때문에 접미사 f를 사용하면 구분을 할 수 있어서 접미사 d는 생략을 허용합니다.
따라서, 리터럴에 붙이는 접미사는 정수형의 L , 실수형의 f 만 주의하시면 됩니다.
*접미사는 대소문자를 구별하지 않지만 L 의 소문자 l 은 숫자 1 과 혼동되기 쉽기 때문에 대문자를 사용하는 것이 좋습니다.
0b, 0x 와 같은 진수를 나타내는 접두사 또한 대소문자를 구별하지 않습니다.
변수와 리터럴의 타입 불일치
범위가 '변수 > 리터럴' 인 경우 : OK
- int i = 'A'; int > char, 'A' = 65
- long l = 123; long > int
- double l = 3.14f; double > float
범위가 '변수 < 리터럴' 인 경우 : Error
- int i = 30_0000_0000; int의 범위(대략 20억)를 넘습니다.
- long l = 3.14f; long < float
- long(8bye), float(4byte)라 가능할 것 같지만
*실수형은 정수형 보다 저장 범위가 훨씬 넓기 때문에 Error가 발생합니다.
- float f = 3.14; float < double;
byte, short 변수에 int 리터럴 저장 : OK
- 단, 변수의 타입의 범위 이내여야 합니다. ( -128<byte<127 / -32,768<short<32,767)
기본형
논리형 : boolean ture/false
조건식, 논리적 계산에 사용
문자형 : char
변수 당 하나의 문자만 저장(여러 개 문자 String)
정수형 : byte, short, int, long
정수 값 저장
주로 int, long 사용 byte는 이진 데이터 다루는데 사용
default 타입은 int
실수형 : float, double
실수 값 저장
default 타입은 double
실수형 표현 범위
정밀도는 소수점 몇자리 까지 오차없이 표현할 수 있는가를 뜻한다.
S는 부호 즉, 양수인지 음수인지를 표현합니다.
E는 지수 즉, 2의 지수를 표현합니다.
M은 가수 즉, 소수점 이하를 표현합니다.
위처럼 실수형은 정수형과는 저장방식이 다르기 때문에 오차가 발생합니다.
정밀도가 어떻게 계산되었는지 간단하게 보겠습니다.
- float의 M 즉, 가수는 23자리인데 정규화를 통해서 24자리까지 표현 가능합니다.
*관계형 데이터베이스의 설계에서 중복을 최소화하게 데이터를 구조화하는 프로세스를 정규화(Normalization)
- 따라서 2^24 까지 표현이 가능한데 2^24는 10^7 < 2^24 < 10^8 임으로 정밀도는 7자리 입니다.
- 마찬가지의 이유로 double 정밀도는 15자리 입니다.
또한 실수형은 +-M x 2^E 형태로 저장하기 때문에
int와 같은 4byte 크기의 float이 int 보다 더 큰 범위의 값을 저장 가능한 것입니다.
타입간의 변환 방법
class Variable3_4 {
public static void main(String[] args) {
String str1 = "100";
String str2 = "3.14";
String str3 = "8";
// 문자열 -> 숫자
System.out.println("Integer.parseInt(str) = " + Integer.parseInt(str1));
// Integer.parseInt() 은 int 타입만 가능
// System.out.println("Integer.parseInt(str2) = " + Integer.parseInt(str2)); // Error 발생
System.out.println("Double.parseDouble(str2) = " + Double.parseDouble(str2));
// 문자열 -> 문자
System.out.println("str.charAt(0) = " + str1.charAt(0) + str1.charAt(1) + str1.charAt(2));
// 첫번째 자리, 두번째 자리, 세번째 자리를 나타내는 것이다.
// str2로 작성시 3.1까지 세번째 자리까지 나오게 된다. 3.14까지 작성하고 싶으면 str2.charAt(3)을 추가로 작성해줘야한다.
System.out.println("str2.charAt(0) = " + str3.charAt(0));
}
}
숫자 => 문자
- 숫자 + '0' => 문자
문자 => 숫자
- 문자 - '0' => 숫자
class Variable3_2 {
public static void main(String[] args) {
int num = 5;
char ch = '5';
// 숫자 -> 문자
System.out.println("num = " + num);
// '0' 이 48이기 때문에 결과값을 char 타입으로 변환 필요
System.out.println("num + '0' = " + (char)(num + '0'));
// 문자 -> 숫자
// 문자 형식과 달리 (". .") 내용과 함께 입력이 불가해 print(. .) println(. .)을 입력한다.
System.out.println("ch = " + ch);
System.out.print("ch - '0' = ");
System.out.println(ch - '0');
// '5' 에서 숫자 5로 변환되었기 때문에 결과값 6
System.out.print("ch - '0' + 1 = ");
System.out.println(ch - '0' + 1);
}
}
숫자 => 문자열
- 숫자 + ""=> 문자열
문자 => 문자열
- 문자 + ""=> 문자열
문자열을 숫자, 문자로 변환
1. 문자열 => 숫자
- Integer.parseInt("문자열")
- Double.parseDouble("문자열")
2. 문자열 => 문자
- "문자열".charAt(0)
class Variable4_1 {
public static void main(String[] args) {
char ch1 = 'A'; // 문자
// char ch2 = 'AB'; // Error 발생
// char ch3 = ''; // Error 발생, 빈 문자 불가능
String s1 = "ABC"; // 문자열
String s2 = ""; // 빈 문자열 가능
String s3 = "A"; // 문자 한 개도 문자열!
// 아래 두 표현식 모두 사용 가능하지만 ss2 방식은 거의 사용하지 않음!
String ss1 = "AB";
String ss2 = new String("AB");
System.out.println("ss1 = " + ss1);
System.out.println("ss2 = " + ss2);
}
}
참조형
기본형을 제외한 나머지 타입을 뜻합니다.
- ex) String, System
참조형 변수는 null 또는 메모리 주소를 저장합니다.
- null 은 '어떤 객체의 주소도 저장되지 않음' 을 뜻합니다.
- 타입에 관계없이 변수의 크기가 항상 4byte 입니다. (JVM이 64bit일 경우 8byte)
- 4byte는 2진수로 대략 40억개로, 40억byte(4GB)의 메모리를 다룰 수 있습니다.
문자와 문자열의 차이
class Variable4_1 {
public static void main(String[] args) {
char ch1 = 'A'; // 문자
// char ch2 = 'AB'; // Error 발생
// char ch3 = ''; // Error 발생, 빈 문자 불가능
String s1 = "ABC"; // 문자열
String s2 = ""; // 빈 문자열 가능
String s3 = "A"; // 문자 한 개도 문자열!
// 아래 두 표현식 모두 사용 가능하지만 ss2 방식은 거의 사용하지 않음!
String ss1 = "AB";
String ss2 = new String("AB");
System.out.println("ss1 = " + ss1);
System.out.println("ss2 = " + ss2);
}
}