출처: https://kingpodo.tistory.com/54
각각의 데이터 타입의 범위는 메모리 사용 크기에 결정되는데
byte의 경우로 예를 들자면 byte의 크기는 1바이트이다 1바이트는 8비트의 크기를 갖는다
컴퓨터는 2진수 체계를 사용한다 즉 1비트당 값을 2개(0,1) 가질 수 있다
2비트라면? 00, 01, 10, 11 4개의 값을 가진다 → 2^2개(4개)
3비트 라면? 000, 001, 010, 011, 100, 101, 110, 111 → 2^3개(8개)
따라서 1비트 부터 8비트의 숫자 표현은 2^8개(256개)의 값을 가질 수 있으며 byte는 음수와 양수를 지원한다(signed)
signed 자료형이 음수를 표현하기 위해서는 첫번째 비트를 사용하는데
첫번째 비트가 1이라면 음수, 0이라면 양수가 된다
자바를 만든 제임스 고슬링은 char를 제외한 자료형에 unsigned 키워드를 아예 없애버렸다고 한다
이유는 c++에서 unsinged로 인한 오류를 너무 많이 보고 겪었기 때문에...
기선님 11/21 라이브 방송중 추가 내용
Java 8 버전 부터 unsinged 가 추가되었다고 한다
특정 타입의 데이터를 담는 그릇을 변수라고 하는데 변수 안에 저장되어지는 값을 리터럴이라고 한다
변수에 저장되는 값 그 자체 이며 이 값은 변하지 않는다
int number = 1 // number는 변수, 1은 리터럴
변수에 담을 수 있는 데이터 타입이 있듯이 리터럴 또한 데이터 타입이 있다
int a;
변수를 선언하는 방법이다 변수를 선언하게 되면 Stack 영역에 변수의 메모리 공간이 생긴다
int a;
a = 10;
a라는 변수를 선언하고 a에 10이라는 값으로 a를 초기화 하였다
int a = 10;
변수의 선언과 초기화를 같이 할 수도 있다
자바에서 사용하는 변수의 종류는 3가지 정도가 있다
클래스 변수, 인스턴스 변수, 지역 변수
public class varScope {
int instanceVal; // 인스턴스 변수
static double b = 30; // 클래스 변수
public static void main(String[] args) {
varScope vs = new varScope();
System.out.println(varScope.b);
System.out.println(varScope.instanceVal); // error -> static 키워드가 없기 에러, 인스턴스 생성 후에 호출 가능
System.out.println(vs.instanceVal);
vs.foo("name");
System.out.println(fooNumber); // error -> 메서드내에 선언된 변수(지역변수)는 해당 메서드 내에서만 실행 가능
System.out.println(name); // error -> 매서드에 보내진 매개변수는 매서드가 호출될 때 생성 되고 매서드 실행이 끝나면 소멸
}
public void foo(String name) {
int fooNumber; // 지역변수
fooNumber = 20;
System.out.println(name); // "name"
}
}
자바에서는 2가지 타입변환이 있다
public class CastingTest {
public static void main(String[] args) {
int a = 10;
long b = 20;
b = a; // int 값의 범위가 long 값의 범위보다 적다 따라서 타입 프로모션 가능
a = (int)b; // long 값의 범위가 int 값의 범위보다 크다 따라서 long -> int로 변환 과정 중 값의 손실이 있을 수 있음
}
}
기본 자료형에서의 타입 변환은 해당 자료형의 사이즈로 프로모션인지, 캐스팅인지 따졌다면
참조 자료형에서는 해당 객체가 부모 객체인지, 자식 객체인지로 따진다
public class CastingTest {
public static void main(String[] args) {
Parent parent = new Child(); // 프로모션
Parent parent2 = new Child();
Child child = (Child)parent2; // 캐스팅
}
}
class Parent {
public void getParent() {
System.out.println("parent");
}
}
class Child extends Parent {
public void getChild() {
System.out.println("child");
}
}
Parent parent = new Child(); // 프로모션
Parent 객체는 Child 객체의 부모이다 자바에서 상속은 부모 객체의 있는 것(필드, 메서드 등)을 자식 객체가 그대로 사용 할 수 있게 하는 것이다
따라서 부모 클래스에서 사용할 수 있는 것들을 자식 클래스에서 그대로 사용할 수 있기 때문에 전혀 문제없이 프로모션이 된다
Parent parent2 = new Child(); // 프로모션
Child child = (Child)parent2; // 캐스팅
캐스팅의 경우는 부모 클래스를 자식 클래스로 변환 하는 경우인데 부모 클래스는 자식객체의 메서드나 필드에 접근 할 수 없다 때문에 부모 클래스를 자식 클래스로 프로모션 한 후 자식 클래스에 할당 할때에는 캐스팅을 해야한다
Child child2 = (Child)new Parent(); // 컴파일 오류는 넘겼지만 실행 시에 에러발생
이건 왜 안될까?
child2에 집어 넣으려는 new Parent()를 Child로 형변환 하였지만 실제로는 new Parent()객체이다 때문에 Child 객체에 할당 할 수 없다
public class arrayTest {
public static void main(String[] args) {
int [] arr;
int arr2 [];
int [] arr3 = {1,2,3,4,5}; // 배열의 선언과 초기화를 동시에 함
arr = new int[3];
arr2 = new int[]{1,2,3};
}
}
public class arrayTest {
public static void main(String[] args) {
int [][] arr = new int[3][];
arr[0] = new int[3];
arr[0][0] = 1;
arr[0][1] = 2;
arr[0][2] = 2;
int arr2 [][] = new int[3][];
arr[0] = new int[]{1,2,3};
int [][] arr3 = {{1,2,3}, {4,5,6}}; // 선언과 동시에 초기화
}
}
Java 10 버전부터 추가된 기능입니다.
Java 9 버전 까지는 지역변수에 명시적으로 타입을 지정했지만 var를 사용하면 명시적으로 타입을 지정해주지 않아도 컴파일러가 알아서 타입 추론을 해준다
public class varTest {
public static void main(String[] args) {
String message = "hello java";
var varMessage = "var로 만든 hello java ";
System.out.println(message);
System.out.println(varMessage);
}
}
선언과 동시에 초기화를 해주지 않은 경우
var로 선언된 변수에 null을 할당 한 경우
지역변수가 아닌 다른 스코프에서 사용할 경우
인스턴스 변수
public class varTest {
var aa = "mamama"; // It won't work for non-local variables
...
}
메서드의 매개변수로 사용한 경우
public class varTest {
...
public void getVar(var aa) {
}
}
var를 사용하여 배열을 초기화 한 경우
var arr = {1,2,3}; // Array initializer is not allowed here
var aa = () => {
};