자바 기본기 정리 2

유승선 ·2023년 2월 6일
1

자바 독학

목록 보기
3/10
post-thumbnail

타입 변환

+ 연산에서의 문자열 자동 타입 변환

  • 연산자가 모두 숫자일 경우 덧셈 연산
  • 연산자 중 하나가 문자일 경우 나머지 연산도 문자열로 자동 변환되고 문자열 결합 연산

덧셈 연산은 왼쪽부터 순차적으로 진행한다. 먼저 수행되는 연산이 String을 포함한 연산이라면 뒤에도 쭉 String 연산으로 진행된다.

int val = 3 + 7 // 10 
String str = "3" + 7 // "37" 

String str = 1 + 2 + "3" // 3 + "3" -> "33" 
String str = 1 + "2" + 3 // "123" 
String str = "1" + 2 + 3 // "123" 

굉장히 신기하다고 느낀 부분이다. 파이썬이든 C++든 서로 다른 Type을 더하게 되면 에러가 나와서 강제 타입 변환을 해주는것은 기본인데 자바는 신기하게도 위와 같은 방식으로 String 과 int 타입이 더해진다.

문자열을 기본 타입으로 강제 타입 변환

문자열을 숫자 혹은 다른 타입으로 변환하는거는 코딩테스트를 포함해서 굉장히 흔한 방법이다. C++에서는 to_string 혹은 stoi 같은 방식으로 변환했는데 자바에서는 조금 다르다.

String str = "10"; 
String -> int 
int value = Integer.parseInt(str); 

String -> long 
long value = Long.parseLong(str); 

String -> float 
float value = Float.parseFloat(str); 

위와 반대로 기본 타입을 문자열로 변경해야 하는 경우도 많다. to_string 방식으로 변확하는게 대표적인 예인데 자바는 아래와 같이 사용된다.

String str = String.valueOf(3); 

시스템 입출력

백준과 같은 프로그램을 사용하다보면은 System 인풋을 가져와야 하는 상황이 있다. 예를 들면 백준에서 나오는 input 예시를 txt 파일안에 담고 그 텍스트 파일을 가져와서 테스트를 하는 상황이다.

시스템 입출력을 C++ 에서는 쉽게 iostream을 임포트 한 다음에 cin 같은 방법을 사용했지만 자바에서는 다른 여러가지 방법중에 Scanner 클래스를 사용하면 쉽게 문자열을 읽을 수 있는거같다.

import java.util.Scanner; 

Scanner scanner = new Scanner(System.in); 

//스캐너 매서드 
scanner.next() //다음 토큰을 문자열로 리턴 
scanner.nextInt() //다음 토큰을 int 타입으로 리턴 
scaanner.nextFloat() //다음토큰을 int 타입으로 리턴 
scanner.nextLine() //키보드로부터 (엔터)를 받을때까지 입력받은 문자열을 반환한다. 타입은 String. 

결국 문자열을 읽는 방법은 같지만 어떤 Datatype으로 읽을건지 확인하는 스캐너 클래스가 괜찮다고 생각했다. 참고로 스캐너를 보다보니 캐릭터를 가지고 오는 함수가 없어서 의아해서 찾아봤다.

String something = scanner.next(); 
char c = something.charAt(0); 

스트링에서 캐릭터를 가지고 올 수 있는 charAt(index) 방식으로 캐릭터를 가지고 오는건 살짝 불편한거같다.

참조타입과 참조변수

이 부분은 학원에서 내가 수업을 할때도 아이들한테 여러번 설명하는 부분이었지만 내 공부로 자세히 보다보니 이해가 더 잘되었다.

Primitive 데이터 타입과 Non-primitive 데이터 타입 (reference type)은 생성되는 과정도 별개고 관리되는 방법도 일반적인 방법하고는 다르다.

대학교 2학년때쯤 배우는 내용같지만 Primitive 데이터 타입에는 값이 바로 지정되는 반면에 참조 타입 같은 경우 힙 영역에 객체가 생성되고 그 주소가 변수로 저장된다. 즉, 변수가 가진 값이랑 그 값이 가르키고 있는 실질적인 객체가 존재한다는 것이다.

메모리 사용 영역

기본적이지만 잊기 쉬운 부분이다. java 소스 코드를 컴파일 하게되면 .class 바이트 코드 파일이 생성되는데 이 생성된 바이트 코드 파일은 메소드 영역에 로딩된다 (클래스 바이트 코드를 메소드 영역에 저장하는것). 이 과정으로 저장된 클래스를 가지고 객체를 만들고 변수를 생성할 수 있다.

메소드 영역 -> 클래스의 바이트 코드들 저장 (정적 필드, 상수, 생성자, 메소드 코드 등을 분류)
힙 영역 -> 객체와 배열이 생성되는 영역
JVM 스택 영역 : 메소드가 호출되면 프레임이 추가되고 메소드가 종료되면 프레임이 제거된다.

JVM 스택 영역

메소드가 호출되면 프레임이 추가되고 메소드가 종료되면 프레임이 제거된다.

if 문이 선언된 블록이 끝나면 v2, v3는 프레임 영역에서 제거된다.

String 타입

  • String 변수에 문자열 리터럴을 넣을 경우 힙 영역에 String 객체가 생성되고 변수는 String 객체를 참조한다.
  • 문자열 리터럴이 동일한 경우 같은 String 객체의 번지를 공유한다.

New 연산자

String name1 = new String("신용권"); 
String name2 = new  String("신용권"); 

  • new 연산자를 사용하게 되면 힙 영역에 새로운 String 객체를 생성하게 된다. 만약에 기존에 만든 다른 String 변수가 같은 내용의 문자열을 참조하고 있다해도 new 연산자를 사용해서 새로운 객체를 만들게 되면 둘은 서로 다른 객체를 바라보고 있다.
String name1 = "신용권";
String name2 = "신용권";
String name3 = new String("신용권");

name1 == name2; // true
name1 == name3; // false

문자열 비교시

자바에서는 문자열 비교시 C++이나 다른 언어에서 사용하던 == 연산자가 아닌 equals() 를 사용해서 비교 한다고 한다. 주소를 비교하는 == 비해서 equals()는 안에 있는 내용물을 비교해서 더 정확한 비교 연산을 할 수 있다.

쓰레기 수집기

String hobby = "여행"; 
hobby = null

위와 같이 처음 스택 영역에서 hobby 변수에 리터럴을 주면서 힙 영역에 문자열 객체가 생겼다. 그렇지만 그 후에 hobby의 참조값을 null로 만들게 되면서 힙 영역에 남아있는 문자열 객체는 아무 참조 없이 단독으로 생성됐는데 이것을 쓰레기 객체라고 한다. 왜냐면은 참조가 있어야지 이 객체를 찾고 사용할 수 있는데 이제는 사용할 수 없게 되었기 때문이다.

그렇기 때문에 쓰레기 수집기 (Garbage Collector)가 이런 힙 영역에 참조를 잃은 객체들을 제거한다. 사용자의 다른 노력 없이 메모리를 관리할 수 있다는 소리다.

profile
성장하는 사람

0개의 댓글