본문 바로가기
JAVA

[Java] 데이터, 변수, 배열

by 햄과함께 2020. 12. 27.
320x100

Primitive Type

종류 범위 크기 기본 값
byte -128 ~ 127 1 byte 0
short -32,768 ~ 32,767 2 byte 0
int -231 ~ 231-1 4 byte 0
long -263 ~ 263-1 8 byte 0L
float 1.40239846E-45 ~ 3.40282347E+38 4 byte 0.0f
double 4.94065645841246544E - 324 ~ 1.79769313486231570E + 308 8 byte 0.0d
boolean true, false 1 byte false
char '\u0000'(0) ~ '\uffff'(65,535) 2 byte '\u0000'

참고 : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html.


Primitive Type vs Reference Type

primitive type

int a = 1;
int b = a;
b = 3; // => 변수 : a=1, b=3

데이터에 할당된 메모리에 값이 저장된다.
위와 같이 b = a 와 같이 b에 a 값을 복사했다면 b 값은 a 값과 같아진다.
만약 b를 3으로 변경했다고 하더라도 a 값은 여전히 1이다.

reference Type

class Member { String name; };

Member a = new Member("a");
Member b = a;
b.setName("b"); // => 변수 : a.name="b", b.name="b"

원시 데이터형(primitive type)을 제외한 모든 데이터 타입은 참조형(reference) 타입이다.
기본값은 Null이다. (그래서 NPE가 많이 발생하는 걸까나). 데이터에 할당된 메모리에 원본 데이터의 주소 값이 저장된다.
위 코드에서 변수 a에는 회원 객체 정보가 저장되는게 아닌 회원 객체 정보가 저장된 메모리 주소 값이 저장된다. 따라서 b = a를 한 b 또한 a 회원 객체의 메모리 주소 값이 저장된다. 회원 정보가 어디에 저장되어 있는지 알려주는 것이기 때문에 b.setName을 하면 b가 가리키는 회원 메모리 정보를 바꾸게 되고, a와 b는 같은 메모리 주소를 가리키고 있기 때문에 a.name과 b.name은 같은 결과를 가진다.

cf) 자바에서 제공하는 String 클래스는 참조형 타입이긴 하나 동작은 primitive 타입처럼 동작하게 설계되어 있다.


Literal

변하지 않는 고정된 값.

int num = 10; // num은 변수. 10은 literal

cf) 상수

변하지 않는 변수.
변수가 초기화된 후 값을 바꾸지 못한다.

final int MAX_SIZE = 100;

참고 : https://velog.io/@ditt/Java-String-literal-vs-new-String


변수

선언

int number;
double number;
float number;

초기화

int number = 1;
double number = 1;
float number =1;

스코프, 라이프타임

지역 변수는 변수를 선언한 블록에서만 사용 가능하며 해당 스코프가 종료될 때, 같이 메모리 해제된다.

import java.util.*;
import java.lang.*;


class Member {
  static String STATIC = "static";
  String name;
       
  Member(String name) {
    this.name = name;
  }
    
    void print() {
        System.out.println(name); // possible
    }
}

class Rextester {
    public static void main(String args[]) {
        Member member1 = new Member("1번 멤버");
        Member member2 = new Member("2번 멤버");
        System.out.println(Member.name); // error
        System.out.println(Member.STATIC); // possible
        System.out.println(member1.STATIC); // error
        member1.print();
        member2.print();
    }
}

 

단, static 변수(정적 변수)는 객체에 종속되는 값이 아닌 같은 클래스 타입들은 하나의 정적 변수를 보기 때문에 Member.STATIC 처럼 클래스에서 접근해야 한다.
또한 생명주기가 클래스가 아닌 프로그램 수명과 같으므로 프로그램이 종료되기 전까지 유지된다.


타입 변환

변수 타입 변환

int intV = 10;
float floatV = intV;
System.out.println(floatV);
// 출력 : 10.0

묵시적 변환

int intV = 10; float floatV = intV; System.out.println(floatV); // 출력 : 10.0

intV 의 타입에 영향을 줄만한 코드를 짜지 않아도 float로 타입이 변환된다.

float floatV = 10F;
int intV = floatV;
System.out.println(intV);
// /HelloWorld.java:20: error: incompatible types: possible lossy conversion from float to int
//      int intV = floatV;
//                 ^
// 1 error

int 범위는 float 범위에 포함되어 있어서 int -> float로 변환시에는 별다른 문제가 없었다.
하지만 반대인 float -> int 는 값을 손실할 수 있기 때문에 에러가 발생한다.


명시적 변환

int intV = 10;
System.out.println((float)intV);
// 출력 : 10.0

타입 캐스팅 (float) 으로 int형 변수를 float형으로 변환해주었다.

float floatV = 10.9F;
System.out.println((int)floatV);
// 출력 : 10

타입 캐스팅은 묵시적 변환과 달리 데이터 손실이 있는 변환이라도 에러 없이 변환된다.
변환 시 저장할 수 있는 범위만 저장되므로 실수형 타입(float) 에서 정수형 타입(int)로의 변환 결과는 소수점 아래의 데이터를 손실한다.


타입 프로모션

  1. byte, short, char 표현식을 평가할 때 int로 변환(승격)시킨다.
  2. 표현식에 서로 다른 타입이 있는 경우 더 큰 범위를 가진 타입으로 변환 후 수행한다.
Byte < Short < Int < Long < Float < Double

참고 : https://www.geeksforgeeks.org/type-conversion-java-examples/.


배열

array

1차원

// #1
int[] array = {1, 2, 3, 4};
        
// #2
int[] array2 = new int[4];
array2[0] = 1;
array2[1] = 2;
array2[2] = 3;
array2[3] = 4;

 

2차원

// #1
int[][] array = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        
// #2
int[][] array2 = new int[3][3];
array2[0][0] = 1;
        
// #3
int[][] arry3 = new int[3][];
array[0] = {1,2,3}; // error
array[1] = new int[]{4, 5, 6}; 
array[2] = new int[3];

타입 추론, var (java 11 이상)

변수의 타입을 명시하지 않아도 컴파일러가 해당 변수의 타입을 유추하여 타입을 정해준다.

// jdk 11.0.4

var temp = "문자열";
System.out.println(temp.getClass().getSimpleName());
// 출력 : String

var m = new Member("member");
System.out.println(m.getClass().getSimpleName());
// 출력 : Member
320x100

'JAVA' 카테고리의 다른 글

[Java] 멀티쓰레드  (0) 2021.01.23
[Java] 패키지  (0) 2020.12.27
[Java] JVM  (0) 2020.12.27
[Java] 상속(Inheritance)  (0) 2020.12.24
[Java] 이진검색트리(BST) 구현  (0) 2020.12.19

댓글