본문 바로가기

Backend/Study Halle - Java

온라인 자바 스터디 2주차 - (2) 타입의 변환, var 그리고 배열

 

타입의 변환

타입변환이란 변수 또는 상수의 타입을 다른 타입으로 변환하는 것을 말한다.

프로그램에서 값의 대입이나 연산을 수행할 때는 같은 타입끼리만 가능하다. 그래서 연산을 수행하기 전에 같은 타입으로 만들어야 하는데, 변수나 상수를 다른 타입으로 변환하는 것을 '타입변환' 이라고 한다.

형변환에는 개발자가 명시적으로 지정하지 않아도 묵시적으로 이루어지는 자동타입변환과 개발자가 명시해야만 이루어지는 강제타입변환이 있다.

 

자동타입변환(Promotion)

자동 형변환은 프로그램 실행 도중에 자동적으로 형변환(타입변환)이 일어나는 것을 말한다. 자동 형변환은 작은 메모리 크기의 데이터 타입을 큰 메모리 크기의 데이터 타입으로 맞춘다. 정수와 실수 중에선 실수에 우선적으로 맞춘다. 프로모션이 승진이라는 뜻이 있다. 작은 타입과 큰 타입이 있을 땐 작은 타입이 큰 타입으로 승진된다는 개념으로 이해하면 쉽다. 당연하게도 반대로(큰 타입을 형변환 없이 작은 타입으로 변환)하려고하면 컴파일 에러가 난다. 승진은 가능하지만 강등은 안된다는 것.

 

int intType = 1;
double doubleType = 1.5;
	
System.out.println(intType + doubleType); //결과 2.5 (자동으로 더블타입으로 프로모션됨)

 

강제타입변환(Casting)

자동타입변환 조건을 갖추지 못할 때는 변환이 안될까? 그렇지 않다. 자동타입변환이 불가능할 때 쓰는 것이 강제타입변환이다. 개발자가 원하는대로 변환을 하며 변수앞에 '(변환타입)'을 작성한다. 하지만 이 경우에 주의해야 할 것이 있는데, (변환하려는)작은 타입의 최대 값을 주의해야 한다는 것이다. 해당 타입(변수)이 소화할 수 없는 값을 넣어주면 엉뚱한 값이 나오는 오버플로우 현상이 생긴다. 참고로, 자동타입변환이 되는 상황에도 강제타입변환으로 타입변환이 가능하다. 

 

int a = 10;
System.out.println((double)a); //int 형이라면 10이 나오겠지만, 형변환으로 10.0이 출력
		
double b = 1.999;
System.out.println((int)b); //0.999를 잘라버리고 int 형이 가능한 1만 나온다. 이 경우 무조건 내림이다.

 

 

타입추론(Type Interface)

타입추론이란 정적 타이핑을 지원하는 언어에서 타입이 정해지지 않은 변수에 대해서 컴파일러에게 변수의 타입을 스스로 찾아내도록 맡기는 기능이다. 타입 추론이 가능하다는 얘기는 곧 타입을 명시하지 않아도 된다는 이야긴데 즉, 코드량을 좀더 줄여 코드의 가독성을 높일 수 있다는 이야기이다. 자바 10부터 자바에서도 var 를 사용할 수 있다는 것을 오늘  처음 알았다. 자바 10이 나오기 전에는 일반변수에 대해서는 타입추론이 지원되지 않고, generics와 lambda식에 대해서만 타입 추론이 지원되고 있었다. 

 

var

// java 9 이하
String message = "Hello";
// java 10 이상
var message = "Hello";

// java 9 이하
var empList = new ArrayList<>();
// java 10 이상
var empList = new ArrayList<Employee>();

 

주의

  • var는 초기화 없이 사용이 불가능하다.
    예) var n; // 에러
  • null 초기화로도 사용이 불가능하다.
    예) var n = null; //에러
  • 로컬 변수 안에서만 사용이 가능하다.
    예) public var = "hello" //에러
  • 람다표현에서는 명백한 타겟 타입이 필요하므로 var는 사용될 수 없다.
    예) var p = (String s) -> s.length() > 10; //에러
  • 배열에서도 명백한 타겟 타입이 필요하므로 var 사용과 동시에 데이터 초기화가 불가능하다. 
    예) var arr = {1,2,3} //에러 

 

 

 

 

배열(Array)

 

 

 

 

배열은 여러개의 데이터를 저장할 수 있는 자료 구조로, 순서를 나타내는 정수형 배열 첨자를 사용해서 데이터에 액세스 할 수 있음. 자바 배열은 한번 크기가 정해지면 크기를 변경할 수 없다.

 

 

 

특징

  • 여러 개의 값을 관리할 수 있다.
  • 배열은 하나의 공간을 갖게되고, 그 공간에 값이 직접 들어가는 것이 아니라, 값이 들어있는 다른공간의 위치를 알려준다 (참조형)
  • 배열은 다 똑같은 타입의 값만 받을 수 있고, 어떠한 형태의 값을 받는지는 선언을 할 때 지정한다.
  • 배열은 객체이므로 변수만 선언할 경우 실체 객체가 없으므로 값은 null이다. 

2차원 배열

  • 2차원 구조는 보통 표 구조에서 사용한다. ex) 성적표.
  • 하지만 표 구조를 구현하기 위해서는 print 쓴 후 다음 행이 필요할 때 println으로 구현한다.
  • 행 : row -> 행 인덱스 (i)
  • 열 : column -> 열 인덱스 (j)

선언

  • 타입[]([]) 배열이름;
  • 타입 배열이름[]([]);
  • 크기를 지정하지 않은 null 배열;
// 1차원 배열
int[] grade1 = new int[3]; // 길이가 3인 int형 배열의 선언 및 생성
int grade2[] = new int[3]; // 길이가 3인 int형 배열의 선언 및 생성
int[] grade3; // int 형 null 배열

// 2차원 배열
int [][] a = new int [3][2]; // 3행 2열 (3줄 2칸)
int a[][] = new int [3][2]; 
int [][] a; // int 형 null, null 배열

 

 

배열의 초기화

데이터 타입초기 값
char'\u0000'
byte, short, int0
long0L
float0.0F
double0.0 또는 0.0D
booleanfalse
배열, 인스턴스 등null

 

int[] grade1 = {70, 90, 80};          // 배열의 선언과 동시에 초기화할 수 있음.

int[] grade2 = new int[]{70, 90, 80}; // 배열의 선언과 동시에 초기화할 수 있음.

int[] grade3;

// grade3 = {70, 90, 80};             // 이미 선언된 배열을 이 방법으로 초기화하면 오류가 발생함.

int[] grade4;

grade4 = new int[]{70, 90, 80};       // 이미 선언된 배열은 이 방법으로만 초기화할 수 있음.

 

 

배열에 요소 삽입

  • 하나씩 삽입
grade1[0] = 85; 
grade1[1] = 65;
grade1[2] = 90;

a[0][0] = 100;
a[0][1] = 200;
a[1][0] = 300;
a[1][1] = 400;
a[2][0] = 500;
a[2][1] = 600;

 

  • 반복문으로 삽입
for (int i = 0; i < grade1.length; i++) {
    grade[i]=i; // grade1.length 가 3이라면 grade[0]=0, grade[1]=1, grade[2]=2
}

for (int i=0; i < 3; i++) {
	for (int j=0; j<2; j++) {
		System.out.println(a[i][j]);
	}
}

 

 

배열의 요소 확인

  • 기존 for문
    -for(int i=0; i<배열의 길이; i++)
int[] gragde1 = {1, 2, 3};
for (int i=0; i<grade1.length; i++) {
     System.out.println(grade[i]);   //1, 2, 3 이 한줄씩 출력
}

int[][] a = {
	{100, 200}, 
    {300, 400}, 
	{500, 600} 
};
for (int i = 0; i < a.length; i++) {  // a.length : a의 번지수에 데이터가 몇개 있느냐 위의 경우에는 3행이기 때문에 3개. a[i].length: a[i]의 번지수에 데이터가 몇개 있느냐.  
	for (int j = 0; j < a[i].length; j++) { // a[i] 행을 의미하는 문자를 넣어야 됨. j는 행(줄)이 아니기 때문에 j값을 넣으면 문법이 안됨.
		System.out.print(a[i][j] + "\t" );
	} // inner for 
	System.out.println();
} // out for

 

  • 향상된 for문 (1.5버전부터 가능)
    - for( 배열의 요소값 : 반복대상 배열명)
int[] gragde1 = {1, 2, 3};
for (int val : grade1) {
     System.out.println(val);   //1, 2, 3 이 한줄씩 출력
}

/*출력
1
2
3
*/

int[][] b = {
	{600, 500}, 
	{400, 300}, 
	{200, 100} 
};

for (int[] val : b) {
	for (int val2 : val) {
		System.out.print(val2+"\t");
	}
	System.out.println();   
}
        
/*출력
600	500	
400	300	
200	100
*/        

 

  • toString(), deepToString()
int[] gragde1 = {1, 2, 3};
System.out.println(Arrays.toString(grade1)); // {1,2,3} 

int [][] a = new int[2][3]; //a.length == 2
a[0] = new int[2]; // a[0].length == 2
a[0][0] = 10;
a[0][1] = 20;
		
a[1][0] = 30;
a[1][1] = 40;
a[1][2] = 50;
System.out.println(Arrays.deepToString(a)); // {{10,20},{30,40,50}}

 

 

 

 

 

 


참고


stage-loving-developers.tistory.com/8

kephilab.tistory.com/27

seongsillvanas.tistory.com/9

www.baeldung.com/java-10-local-variable-type-inference

velog.io/@bk_log/Java-%ED%83%80%EC%9E%85-%EC%B6%94%EB%A1%A0

https://offbyone.tistory.com/192

velog.io/@yoop/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%B0%B0%EC%97%B4www.tcpschool.com/java/java_array_oneDimensional