public class HalloWorld {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
1, 인스턴스 변수: 클래스 내부에 있는 변수, 인스턴스 생성해야지만 사용가능o
ex. private int num;
2. static 변수: 클래스 올라갈 때 메모리에 같이 올라가서 인스턴스 생성없이 사용가능o
ex. static private int num;
3. 지역변수: 함수안에서 선언된 변수
4. 전역변수:
- 전역변수(객체변수): 같은 클래스안에서 어디든지 호출 가능o
- 전역변수(클래스변수): 다른 클래스에서 어디든지 호출 가능o
class Main{
int global_int; // 전역변수(객체변수)
static int global_static_int; //전역변수(클래스변수)
public double getArea(){
private int radius; // 지역변수 (함수 끝나면 메모리에서 사라짐)
...
}
}
할당(Assign)
을 의미int num;
num = 256;
int appleNum = 10;
합성어를 사용 시, 뒤에 오는 단어 첫글자를 대문자로 사용한다. 해당 표기법을 Camel Case 라고 한다.
abstract, assert, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, enum, extends, false, final, finally, float, for, if, goto, implements, import, instanceof, int, interface, long, native, new, null, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, true, try, void, volatile, while
int num = 100;
변수값에 처음으로 할당하는 것을 변수 초기화(initialization)
라고 한다.
자바에서 =
는 대입(Assign)을 의미한다.
int num1;
num1 = 10;
int num2 = 20;
int num3 = num1 + num2; // 10 + 20
System.out.println(num1 + " + " + num2 + " = " + num3);
int는 4Byte 만큼의 메모리 공간이 필요하기 때문에 위와 같이 각 iut변수마다 4씩 차지하는 것을 볼 수 있고
OS가 메모리에 변수를 올리기 때문에 물리적 순서는 위와 같지 않을 수 있다.
자료형 | 범위 | 크기(byte) | 기본값 |
---|---|---|---|
boolean | true, false | 1 | false |
char | 0 ~ 65,535 (유니코드 문자) | 2 | '\u0000' |
byte | -128 ~ 127 | 1 | 0 |
short | -32,768 ~ 32,767 | 2 | 0 |
int | -2,147,483,648 ~ 2,147,483,647 | 4 | 0 |
long | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | 8 | 0L |
float | ±1.4E-45 ~ 3.4E38 | 4 | 0.0f |
double | ±4.9E-324 ~ 1.8E308 | 8 | 0.0 또는 0.0d |
double num = 0.1;
for(int i = 0; i < 1000; i++) {
num += 0.1;
}
System.out.println(num);
해당 코드를 실행시켰을 때, 100.09999999999859
해당 결과가 나온다. 이러한 오차가 나는 이유는 실수를 이진수로 표현해서 나오는 오차이다.
// 문자
char ch1 = '하';
char ch2 = '이';
// 문자열
String str1 = "하이";
char ch1 = '가';
'가' 를 메모리에 담기 위해 숫자로 Encoding
숫자는 문자로 decoding
char ch1 = '헐';
char ch2 = '확';
char ch3 = 54736; // 문자 '헐'의 유니코드 값
char ch4 = 54869; // 문자 '확'의 유니코드 값
char ch5 = 0xD5D0;
char ch6 = 0xD655;
System.out.println(ch2 + " " + ch2);
System.out.println(ch3 + " " + ch4);
System.out.println(ch5 + " " + ch6);
Java에서 문자열을 생성하는 과정은 2가지 방법이 있다.
1. 문자열 리터럴(Literal)을 사용
public class Main {
public static void main(String[] args) {
String strLiteral1 = "TEST";
String strLiteral3 = "TEST";
String strLiteral2 = "Java";
}
}
2. new String()을 사용
public class Main {
public static void main(String[] args) {
String strObject1 = new String("TEST");
String strObject2 = new String("TEST");
String strObject3 = new String("Java");
}
}
문자열 리터럴(Literal)의 생성 과정
public class Main {
public static void main(String[] args) {
String strLiteral1 = "TEST"; // 1번 과정
String strLiteral2 = "TEST"; // 2번 과정
String strLiteral3 = "Java"; // 3번 과정
}
}
public class Main {
public static void main(String[] args) {
String strObject1 = new String("TEST"); // 1번 과정
String strObject2 = new String("Java"); // 2번 과정
String strObject3 = new String("TEST"); // 3번 과정
}
}
1. Java Heap에 "TEST"가 생성됩니다.
2. Java Heap에 "TEST"가 생성됩니다.
3. Java Heap에 "Java"가 생성됩니다.
문자열 리터럴(Literal)과 다르게 new String()으로 생성된 문자열은 Heap 영역에 생성이 된다. 그리고 동일한 문자열이라도 기존의 문자열을 참조하지 않고 새로 생성된다.
String Pool은 Heap의 저장 영역이다. JVM은 과도한 String 개체의 수를 줄이고자 문자열 리터럴이 생성될 때마다 String Pool을 체크한다. 문자열이 이미 String Pool에 존재하는 경우에는 인스턴스에 대한 참조가 반환된다. 존재하지 않으면 새로운 인스턴스가 String Pool에 생성이 된다.
일반적으로 리터럴(Literal)을 사용하는 것이 읽기가 더 쉬우며, 컴파일러가 코드를 효율적으로 최적화한다.
public class Main {
public static void main(String[] args) {
String strLiteral1 = "TEST";
String strLiteral2 = "TEST";
String strLiteral3 = "Java";
String strObject1 = new String("TEST");
String strObject2 = new String("TEST");
String strObject3 = new String("Java");
System.out.println("strLiteral1 == strLiteral2 : " + (strLiteral1 == strLiteral2));
System.out.println("strObject1 == strObject2 : " + (strObject1 == strObject2));
System.out.println("strLiteral1 == strObject1 : " + (strLiteral1 == strObject1) + "\n");
System.out.println("strLiteral1.equals(strLiteral2) : " + (strLiteral1.equals(strLiteral2)));
System.out.println("strObject1.equals(strObject2) : " + (strObject1.equals(strObject2)));
System.out.println("strLiteral1.equals(strObject1) : " + (strLiteral1.equals(strObject1)));
}
}
실행결과는 다음과 같다.
동일한 메모리 공간인지 비교를 하는 연산자(operator)
객체의 내용을 비교하는 메소드
위 코드의 문자열 리터럴(Literal)과 new String() 객체의 Heap 메모리 구조는 아래 그림과 같다.
▶ strLiteral1 == strLiteral2
strLiteral1과 strLiter2는 동일한 공간을 참조하고 있다.
즉, 참조하는 주소가 같으므로 true이다.
▶ strObject1 == strObject2
strObject1과 strObject2는 다른 공간을 참조하고 있다.
즉, 참조하는 주소가 다르므로 false이다.
▶ strLiteral1 == strObject1
strLiteral1과 strObject2는 다른 공간을 참조하고 있다.
strLiteral1은 String Pool 내부의 공간을 참조힌다.
strObject2는 String Pool 외부의 공간을 참조한다.
즉, 참조하는 주소가 다르므로 false이다.
▶ .equals()
변수가 참조하는 공간에 있는 값의 일치여부를 판단하기 때문에 true이다.
int num1 = 10;
int num2 = 20;
System.out.println(num1 < num2);
결과값 true 반환
1, 가리키는 값이 없다
2. GC(Garbage Collector)로 하여금 해당 메모리를 회수 해도 좋다는 의미
short num1 = 11;
short num2 = 22;
sout(num1 + num2); // 33 -> int타입(int이하의 타입은 default로 int로 자동형변환된다)
// short로 타입을 유지하고 싶은 경우
short num3 = (short) (num1 + num2);