[Java] 변수(Variable), 타입(Type) 그리고 문자열(String)

Nakjoo·2022년 12월 21일
0

[SEB_BE_43]

목록 보기
4/29

0. 자바의 특징

제목에 적어 놓은 것 들을 알아보기 전에 잠깐 자바의 특징을 살펴본다면,

  • 운영체제에 독립적
  • 객체 지향 언어(Object Oriented Programming, OOP)
  • 함수형 프로그래밍 지원
  • 자동 메모리 관리(Garbage Collection)

으로 볼 수 있다.

0.1. JVM(Java Virtual Machine)

자바는 컴파일러(Compiler)를 통해 기계어(Machine Language)로 변환되는 언어이다.

컴파일이란 특정 프로그래밍 언어를 기계가 이해할 수 있는 언어로 옮기는 번역 과정으로, 여기서는 자바 언어를 JVM이 이해할 수 있는 코드로 변환하는 것을 의미한다. JVM은 바이트코드를 운영체제에 맞는 기계어로 변환해준다.

1. 변수

변수(Variable)는 값이 변할 수 있는 데이터를 임시적으로 저장하기 위한 수단

변수에 저장한다는 말은 단순히 하나의 단어에 값을 저장하는 것이 아닌, 실제로는 값을 저장할 수 있는 메모리 공간을 확보하고, 사람들이 알아보기 힘든 주소값 대신 사람이 식별할 수 있는 이름을 붙인 것이다.

1.1. 값 할당

변수에 값을 저장하는 것을 할당 또는 대입이라고 한다. 변수에 값을 할당하는 방법은 간단하다. 대입 연산자 =를 사용하면 된다.

class Example {
	public static void main(String[] args) {
    	int num; // 변수 선언
        num = 1; // 값 할당
    }
}

대입 연산자를 설명하자면, 말 그대로 어떤 값을 변수에 대입 또는 할당시켜주는 연산자를 의미한다.
좌향 = 우항;과 같은 형식으로 사용하며, 우항에는 값이, 좌항에는 변수가 위치해야 한다.

아래 예시 처럼 num을 1로 초기화한 후, 2로 재할당하면 num에 저장되어 있던 1은 사라지고 2가 저장된다.

class Example {
	public static void main(String[] args) {
    	int num = 1; // 변수 선언과 값 할당을 동시에
        num = 2; // 값 할당(재할당)
    }
}

여기에서 변수가 왜 변수라고 불리는지 그 이유를 알 수 있다. 즉, 재할당이 가능하다는 것은 저장하고 있는 값이 변할 수 있는 것을 의미한다. 이처럼 저장하고 있는 값이 바뀔 수 있는 메모리 공간을 변수라고 부른다.

1.3. 변수 명명 규칙

자바에서 변수명은 일반적으로 카멜 케이스(camelCase). 카멜 케이스란 낙타 등 모양을 닮았다고 해서 붙여진 이름으로, 두 번째 단어부터 대문자로 시작해 구분한다.

int camelCase;

변수명을 영문자, 숫자, _, $를 사용할 수 있으며, 영문자는 대소문자가 구별된다. 즉, aA는 다른 문자로 인식된다.

int num;
int NUM; // num과 다른 변수이다.
int num_1;
int num$1;

숫자로 시작하는 변수명은 사용할 수 없다.

int 10Age; // Error

자바에서 이미 사용중인 예약어(reserved wor)는 변수명으로 사용할 수 없다.

int byte; // Error
int class; // Error

2. 상수

상수(Constant)는 변하지 말아야 할 데이터를 임시적으로 저장히기 위한 수단

상수는 final이라는 키워드를 사용해 선언할 수 있으며, 곤례적으로 대문자에 언더바(_)를 넣어 구분하는 SCREAMING_SNAKE_CASE를 사용한다.

final double CALCULATOR_PI = 3.14;

2.1. 상수를 사용하는 이유

  • 프로그램이 실행되면서 값이 변하면 안되는 경우
  • 코드 가독성을 높이고 싶은 경우
  • 코드 유지관리를 손쉽게 하고자 하는 경우

3. 리터럴

사전적으로 리터럴(Literal)은 '문자 그대로의'라는 뜻을 가진다. 프로그래밍에서 리터럴이란 문자가 가리키는 값 그 자체를 의미한다.

class Example {
	public static void main(String[] args) {
    	int num; // 변수 선언
        num = 1; // 값 할당
    }
}

위 예제에서 num에 할당하고 있는 1이 바로 리터럴이다.

4. 타입

타입이란 어떤 값의 유형 및 종류를 의미하며, 타입에 따라 값이 차지하는 메모리 공간의 크기와, 값이 저장되는 방식이 결정된다.

  1. 값이 차지하는 메모리 공간의 크기

    • 예를 들어, 정수형 타입의 데이터는 4byte, 문자형 타입의 데이터는 1byte이다.
  2. 값이 저장되는 방식

    • 타입은 저장하고자 하는 값을 그대로 저장하는 기본타입과, 저장하고자하는 값을 임의의 메모리 공간에 저장한 후 그 메모리 공간의 주소를 저장하는 참조타입으로 분류된다.

4.1. 기본 타입과 참조 타입

  • 기본 타입(primitive type)
    • 값을 저장할 때, 데이터의 실제 값이 저장된다.
    • 정수 타입(byte, short, int, long), 실수 타입(float, double), 문자 타입(char), 논리 타입(boolean)
  • 참조 타입(reference type)
    • 값을 저장할 때, 데이터가 저장된 곳을 나타내는 주소값이 저장된다.
    • 객체의 주소를 저장, 8개의 기본형을 제외한 나머지 타입

4.2. 정수 타입

정수 타입은 숫자를 나타내는 타입으로 byte, short, int, long의 총 4개의 타입으로 분류된다.
타입별로 차지하는 메모리 공간의 크기와 표현할 수 있는 범위는 다음과 같다.

정수형 리터럴은 아래와 같이 정수형 변수에 할당할 수 있습니다. 이 때, long 타입 리터럴의 경우에는 리터럴 뒤에 접미사 L 또는 l을 붙여주어야 합니다. 일반적으로, 숫자 1과 혼동을 방지하기 위해 대문자 L을 붙입니다.

// 각 데이터 타입의 표현 범위에 맞는 값을 할당하고 있습니다. 
byte  byteNum  = 123;
short shortNum = 12345;
int   intNum   = 123456789;
long  longNum  = 12345678910L;

// 각 데이터 타입의 표현 범위에 벗어난 값을 할당하고 있어 에러가 발생합니다. 
byte  byteNum  = 130;
short shortNum = 123456;
int   intNum   = 12345678910;

// 숫자가 길면 언더바로 구분할 수 있습니다. 
int   intNum   = 12_345_678_910;
long  longNum  = 12_345_678_910L;

4.3. 실수 타입

실수는 소수점을 가지는 값을 의미하며, float형과 double형으로 분류된다.

실수형 리터럴은 아래와 같이 사용할 수 있습니다. 이 때, double형 리터럴에는 접미사 d를 붙여도, 붙이지 않아도 되지만, float형 리터럴에는 반드시 접미사 f를 붙여주어야 합니다.

float num1 = 3.14f;

double num2 = 3.141592d;
double num3 = 3.141592;

4.4. 논리 타입

논리 타입의 종류는 boolean형 한가지 뿐이다. boolean형은 참 또는 거짓을 저장할 수 있는 데이터 타입으로, 오직 true 혹은 false를 값으로 가진다.

단순히 참과 거짓을 표현하기 위해서는 1bit만 있으면 되지만, JVM이 다룰 수 있는 데이터의 최소 단위가 1byte이기 때문에 boolean형은 1byte(8bit)의 크기를 가진다.

boolean isRainy = true;
boolean isAdult = false;

4.5. 문자 타입

문자 타입은 2byte 크기의 char형 오직 하나만 있다.

문자 타입 변수를 선언하면 해당 변수에 오직 하나의 문자형 리터럴을 저장할 수 있다.

문자형 리터럴을 작성할 때에는 반드시 큰 따옴표("")가 아닌 작은 따옴표('')를 사용해야 한다. 큰 따옴표를 사용하면 문자형 리터럴이 아니라 문자열 리터럴로 인식되기 때문이다.

char letter1 = 'a';
char letter2 = 'ab'; // Error : 단 하나의 문자만 할당 가능
char letter3 = "a"; // Error : 작은 따옴표를 사용해야 함

자바는 유니코드로 문자를 저장한다. 따라서 char letter1 = 'a';와 같이 문자형 리터럴을 문자형 변수에 할당하면 letter에는 영문자 a의 유니코드 숫자값이 저장된다.

반대로 숫자를 문자형 변수에 할당할수도 있다.

char letter = 65;
System.out.println(letter); // 출력 결과 : A

5. 문자열

5.1. String 타입의 변수 선언과 할당

기본적으로 String 타입은 큰따옴표("")로 감싸진 문자열을 의미한다.

String 타입의 변수를 선어나고, 문자열 리터럴을 할당하는 방법은 다음과 같다.

// 문자열 리터럴을 String 타입의 변수 name에 할당하는 방법
String name1 = "Kim Coding";

// String 클래스의 인스턴스를 생성하는 방법
String name2 = new String("Kim Coding");

5.2. String 클래스의 매서드

5.2.1. charAt() 메서드

charAt() 메서드는 해당 문자열의 특정 인덱스에 해당하는 문자를 반환한다. 만약 해당 문자열의 길이보다 큰 인덱스나 음수를 전달하면, 오류가 발생한다.

String str = new String("Java");
System.out.println("문자열 : " + str); // "문자열 : Java"

System.out.println(str.charAt(0)); // 'J'
System.out.println(str.charAt(1)); // 'a'
System.out.println(str.charAt(2)); // 'v'
System.out.println(str.charAt(3)); // 'a'

System.out.println("\ncharAt() 메서드 호출 후 문자열 : " + str);

5.2.2. compareTo() 메서드

compareTo() 메서드는 해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교합니다. 이 메서드는 문자열을 비교할 때 대소문자를 구분하여 비교합니다. 만약 두 문자열이 같다면 0을 반환하며, 해당 문자열이 인수로 전달된 문자열보다 작으면 음수를, 크면 양수를 반환합니다. 만약 문자열을 비교할 때 대소문자를 구분하지 않기를 원한다면, compareToIgnoreCase() 메서드를 사용하면 됩니다.

String str = new String("abcd");
System.out.println("문자열 : " + str);
System.out.println(str.compareTo("bcef"));
System.out.println(str.compareTo("abcd") + "\n");
System.out.println(str.compareTo("Abcd"));
System.out.println(str.compareToIgnoreCase("Abcd"));
System.out.println("compareTo() 메서드 호출 후 문자열 : " + str);

5.2.3. concat() 메서드

concat() 메서드는 해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환합니다. 참고로, concat은 concatenate의 약자로, 사전적으로 연결한다는 의미를 가집니다. 만약 인수로 전달된 문자열의 길이가 0이면, 해당 문자열을 그대로 반환합니다.

String str = new String("Java");
System.out.println("문자열 : " + str);
System.out.println(str.concat("수업"));
System.out.println("concat() 메서드 호출 후 문자열 : " + str);

5.2.4. indexOf() 메서드

indexOf() 메서드는 해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환합니다. 만약 해당 문자열에 전달된 문자나 문자열이 포함되어 있지 않으면 -1을 반환합니다.

String str = new String("Oracle Java");
System.out.println("문자열 : " + str);
System.out.println(str.indexOf('o'));
System.out.println(str.indexOf('a'));
System.out.println(str.indexOf("Java"));
System.out.println("indexOf() 메서드 호출 후 원본 문자열 : " + str);

5.2.5. trim() 메서드

trim() 메서드는 해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거해 줍니다.

String str = new String(" Java     ");
System.out.println("문자열 : " + str);
System.out.println(str + '|');
System.out.println(str.trim() + '|');
System.out.println("trim() 메서드 호출 후 문자열 : " + str);

5.2.6. toLowerCase()와 toUpperCase() 메서드

toLowerCase() 메서드는 해당 문자열의 모든 문자를 소문자로 변환시켜 줍니다. 또한, toUpperCase() 메서드는 해당 문자열의 모든 문자를 대문자로 변환시켜 줍니다.

String str = new String("Java");
System.out.println("문자열 : " + str);
System.out.println(str.toLowerCase());
System.out.println(str.toUpperCase());
System.out.println("두 메서드 호출 후 문자열 : " + str);

5.3. StringTokenizer

StringTokenizer 클래스는 문자열을 우리가 지정한 구분자로 문자열을 쪼개주는 클래스이다. 그렇게 쪼개어진 문자열을 토큰(token)이라고 부른다. StringTokenizer를 사용하기 위해서는 java.util.StringTokenizer를 import해야한다.

import java.util.StringTokenizer;

public static void main(String[] args){
	String str = "This is a string example using StringTokenizer";
	StringTokenizer tokenizer = new StringTokenizer(str);
	System.out.println(str);
	System.out.println();
		
	System.out.println("total tokens:"+tokenizer.countTokens());
	
	while(tokenizer.hasMoreTokens()){
		System.out.println(tokenizer.nextToken());
	}
	System.out.println("total tokens:"+tokenizer.countTokens());
}

자주 사용하는 메서드는 아래와 같다.

  • int countTokens()
    • 남아있는 token의 개수를 반환한다. 전체 token의 개수가 아닌 현재 남아있는 token의 개수이다.
  • boolean hasMoreElements(), boolean hasMoreTokens()
    • 두 메서드의 성능적인 차이는 없다. 둘다 동일한 값을 반환한다. 메서드는 현재 위치 뒤에 있는 문자열에서 하나 이상의 토큰을 사용할 수 있는 경우 true를 반환하고 그렇지 않으면 false를 반환한다.
  • Object nextElement(), String nextToken()
    • 이 두 메서드는 다음의 토큰을 반환한다. 두 가지 메서드는 같은 객체를 반환하는데 반환형은 다르다. nextElement는 Object를, nextToken은 String을 반환한다.

5.4. StringBuilder

StringBuilder는 여러 개의 문자열을 담는 클래스이다.
다음 코드를 통해 어떻게 사용할 수 있는지 확인해보자.

public class Main {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("문자열 ").append("연결");
        String str = stringBuilder.toString();
        System.out.println(stringBuilder);
        System.out.println(str);
    }
}

먼저 StringBuilder의 객체를 생성한 후, append()의 인자로 연결하고자 하는 문자열을 넣어서 StringBuilder의 객체를 통해 호출한다.
또한, 문자열을 출력할 때, 그리고 변수에 문자열을 할당할 때에는 toString() 메서드를 사용하면 된다.

5.5. StringBuffer

String 클래스의 인스턴스는 한 번 생성되면 그 값을 읽기만 할 수 있고, 변경할 수는 없다. 하지만 Stringbuffer 클래스의 인스턴스는 그 값을 변경할 수도 있고, 추가할 수도 있다.

5.5.1. append()

append() 메서드는 인수로 전달된 값을 문자열로 변환한 후, 해당 문자열의 마지막에 추가합니다. 이 메서드는 String 클래스의 concat() 메서드와 같은 결과를 반환하지만, 내부적인 처리 속도가 훨씬 빠릅니다.

StringBuffer str = new StringBuffer("Java");
System.out.println("문자열 : " + str);
System.out.println(str.append(" programming"));
System.out.println("append() 메서드 호출 후 문자열 : " + str);

5.5.2. capacity()

capacity() 메서드는 StringBuffer 인스턴스의 현재 버퍼 크기를 반환한다.

StringBuffer str01 = new StringBuffer();
StringBuffer str02 = new StringBuffer("Java");
System.out.println(str01.capacity());
System.out.println(str02.capacity());


위의 예제처럼 길이가 4인 문자열로 StringBuffer 인스턴스를 생성하면, 기본적으로 생성되는 여유 버퍼 크기인 16에 문자의 길이인 4를 더한 총 20개의 문자를 저장할 수 있는 버퍼가 생성되는 것을 확인할 수 있습니다.

5.5.3. delete()

delete() 메서드는 전달된 인덱스에 해당하는 부분 문자열을 해당 문자열에서 제거합니다. 또한, deleteCharAt() 메서드를 사용하면 특정 위치의 문자 한 개만 제거할 수도 있습니다.

StringBuffer str = new StringBuffer("Java Oracle");
System.out.println("문자열 : " + str);
System.out.println(str.delete(4, 8));
System.out.println(str.deleteCharAt(1));
System.out.println("deleteCharAt() 메소드 호출 후 문자열 : " + str);

delete() 메서드를 사용하여 해당 문자열에서 인덱스가 4인 위치의 문자부터 7인 위치의 문자까지를 삭제하고 있습니다. 이처럼 delete() 메서드는 첫 번째 매개변수로 전달된 인덱스부터 두 번째 매개변수로 전달된 인덱스 바로 앞의 문자까지를 삭제하는 메서드입니다.

5.5.4. insert()

insert() 메서드는 인수로 전달된 값을 문자열로 변환한 후, 해당 문자열의 지정된 인덱스 위치에 추가합니다. 이때 전달된 인덱스가 해당 문자열의 길이와 같으면, append() 메서드와 같은 결과를 반환합니다.

StringBuffer str = new StringBuffer("Java Programming!!");
System.out.println("문자열 : " + str);
System.out.println(str.insert(4, "Script"));
System.out.println("insert() 메서드 호출 후 문자열 : " + str);


위 예제의 세번째 줄에서는 insert() 메서드를 사용하여 해당 문자열에서 인덱스가 4인 위치부터 두 번째 매개변수로 전달된 문자열을 추가하고 있습니다.

0개의 댓글