제목에 적어 놓은 것 들을 알아보기 전에 잠깐 자바의 특징을 살펴본다면,
으로 볼 수 있다.
자바는 컴파일러(Compiler)를 통해 기계어(Machine Language)로 변환되는 언어이다.
컴파일이란 특정 프로그래밍 언어를 기계가 이해할 수 있는 언어로 옮기는 번역 과정으로, 여기서는 자바 언어를 JVM이 이해할 수 있는 코드로 변환하는 것을 의미한다. JVM은 바이트코드를 운영체제에 맞는 기계어로 변환해준다.
변수(Variable)는 값이 변할 수 있는 데이터를 임시적으로 저장하기 위한 수단
변수에 저장한다는 말은 단순히 하나의 단어에 값을 저장하는 것이 아닌, 실제로는 값을 저장할 수 있는 메모리 공간을 확보하고, 사람들이 알아보기 힘든 주소값 대신 사람이 식별할 수 있는 이름을 붙인 것이다.
변수에 값을 저장하는 것을 할당 또는 대입이라고 한다. 변수에 값을 할당하는 방법은 간단하다. 대입 연산자 =
를 사용하면 된다.
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; // 값 할당(재할당)
}
}
여기에서 변수가 왜 변수라고 불리는지 그 이유를 알 수 있다. 즉, 재할당이 가능하다는 것은 저장하고 있는 값이 변할 수 있는 것을 의미한다. 이처럼 저장하고 있는 값이 바뀔 수 있는 메모리 공간을 변수라고 부른다.
자바에서 변수명은 일반적으로 카멜 케이스(camelCase). 카멜 케이스란 낙타 등 모양을 닮았다고 해서 붙여진 이름으로, 두 번째 단어부터 대문자로 시작해 구분한다.
int camelCase;
변수명을 영문자, 숫자, _
, $
를 사용할 수 있으며, 영문자는 대소문자가 구별된다. 즉, a
와 A
는 다른 문자로 인식된다.
int num;
int NUM; // num과 다른 변수이다.
int num_1;
int num$1;
숫자로 시작하는 변수명은 사용할 수 없다.
int 10Age; // Error
자바에서 이미 사용중인 예약어(reserved wor)는 변수명으로 사용할 수 없다.
int byte; // Error
int class; // Error
상수(Constant)는 변하지 말아야 할 데이터를 임시적으로 저장히기 위한 수단
상수는 final
이라는 키워드를 사용해 선언할 수 있으며, 곤례적으로 대문자에 언더바(_)를 넣어 구분하는 SCREAMING_SNAKE_CASE를 사용한다.
final double CALCULATOR_PI = 3.14;
사전적으로 리터럴(Literal)은 '문자 그대로의'라는 뜻을 가진다. 프로그래밍에서 리터럴이란 문자가 가리키는 값 그 자체를 의미한다.
class Example {
public static void main(String[] args) {
int num; // 변수 선언
num = 1; // 값 할당
}
}
위 예제에서 num
에 할당하고 있는 1
이 바로 리터럴이다.
타입이란 어떤 값의 유형 및 종류를 의미하며, 타입에 따라 값이 차지하는 메모리 공간의 크기와, 값이 저장되는 방식이 결정된다.
값이 차지하는 메모리 공간의 크기
값이 저장되는 방식
정수 타입은 숫자를 나타내는 타입으로 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;
실수는 소수점을 가지는 값을 의미하며, float
형과 double
형으로 분류된다.
실수형 리터럴은 아래와 같이 사용할 수 있습니다. 이 때, double
형 리터럴에는 접미사 d
를 붙여도, 붙이지 않아도 되지만, float
형 리터럴에는 반드시 접미사 f
를 붙여주어야 합니다.
float num1 = 3.14f;
double num2 = 3.141592d;
double num3 = 3.141592;
논리 타입의 종류는 boolean
형 한가지 뿐이다. boolean
형은 참 또는 거짓을 저장할 수 있는 데이터 타입으로, 오직 true
혹은 false
를 값으로 가진다.
단순히 참과 거짓을 표현하기 위해서는 1bit만 있으면 되지만, JVM이 다룰 수 있는 데이터의 최소 단위가 1byte이기 때문에 boolean
형은 1byte(8bit)의 크기를 가진다.
boolean isRainy = true;
boolean isAdult = false;
문자 타입은 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
기본적으로 String 타입은 큰따옴표(""
)로 감싸진 문자열을 의미한다.
String 타입의 변수를 선어나고, 문자열 리터럴을 할당하는 방법은 다음과 같다.
// 문자열 리터럴을 String 타입의 변수 name에 할당하는 방법
String name1 = "Kim Coding";
// String 클래스의 인스턴스를 생성하는 방법
String name2 = new String("Kim Coding");
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);
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);
concat()
메서드는 해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환합니다. 참고로, concat은 concatenate의 약자로, 사전적으로 연결한다는 의미를 가집니다. 만약 인수로 전달된 문자열의 길이가 0이면, 해당 문자열을 그대로 반환합니다.
String str = new String("Java");
System.out.println("문자열 : " + str);
System.out.println(str.concat("수업"));
System.out.println("concat() 메서드 호출 후 문자열 : " + str);
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);
trim()
메서드는 해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거해 줍니다.
String str = new String(" Java ");
System.out.println("문자열 : " + str);
System.out.println(str + '|');
System.out.println(str.trim() + '|');
System.out.println("trim() 메서드 호출 후 문자열 : " + str);
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);
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());
}
자주 사용하는 메서드는 아래와 같다.
true
를 반환하고 그렇지 않으면 false
를 반환한다.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()
메서드를 사용하면 된다.
String
클래스의 인스턴스는 한 번 생성되면 그 값을 읽기만 할 수 있고, 변경할 수는 없다. 하지만 Stringbuffer
클래스의 인스턴스는 그 값을 변경할 수도 있고, 추가할 수도 있다.
append()
메서드는 인수로 전달된 값을 문자열로 변환한 후, 해당 문자열의 마지막에 추가합니다. 이 메서드는 String 클래스의 concat() 메서드와 같은 결과를 반환하지만, 내부적인 처리 속도가 훨씬 빠릅니다.
StringBuffer str = new StringBuffer("Java");
System.out.println("문자열 : " + str);
System.out.println(str.append(" programming"));
System.out.println("append() 메서드 호출 후 문자열 : " + str);
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개의 문자를 저장할 수 있는 버퍼가 생성되는 것을 확인할 수 있습니다.
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()
메서드는 첫 번째 매개변수로 전달된 인덱스부터 두 번째 매개변수로 전달된 인덱스 바로 앞의 문자까지를 삭제하는 메서드입니다.
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인 위치부터 두 번째 매개변수로 전달된 문자열을 추가하고 있습니다.