티스토리 뷰
자바의 기본 타입에 대해 처음 공부를 한다면, 가장 먼저 배우는 것이 int, double, String, boolean 일 것이다.
아무것도 모르던 시절에는 그냥 다 원시타입(기본타입)이구나~ 라고 넘겼으나, 사실은 그렇지 않다.
String 클래스는 원시 타입으로 착각할 수 있으나 사실은 원시타입이 아니며 참조형 객체 클래스이다.
예를들어 우리가 int, double byte 이런 원시타입을 Wrapper 클래스로 바꾸어주면 Integer, Double, Byte 이런식으로 바꿀수 있지 않은가? String 은 Integer, Double, Byte 같이 Wrapper 클래스라고 생각하면 된다.
단지 String 의 원시타입은 없을뿐!
(래퍼 클래스라고 불리는 Wrappre Class 에 대해선 추후에 다른 포스팅에서 설명하겠다.)
String 클래스 특징
String 클래스는 다른 클래스들 처럼 클래스의 특징을 모두 지니고 있지만, 특별한 2가지 특징이 있다.
1. 한 번 정의된 문자열은 변경이 불가하다.
= 문자열의 내용을 변경하면 JVM은 수정하는 것이 아닌, 새로운 객체를 생성하고 기존의 객체를 버리는 것이다.
2. 문자열 리터럴을 입력하여 객체를 생성할 때 같은 문자열(=값)끼리 객체를 공유한다
= 메모리의 효율성
이해가 되지 않는 부분이 있을 수도 있을 것이다.
밑에 글에서 좀 더 자세히 설명을 하도록 하겠다.
String 클래스 선언
String 클래스는 2가지의 선언 방법이 있다.
리터럴을 사용한 선언과 new 를 사용한 선언이 있다.
1. 리터럴
String str1 = "hello";
2. new 를 사용한 선언
String str2 = new String("hello");
srt1과 srt2 를 모두 출력해보면 동일하게 "hello" 가 출력이 되어 동일하지만, 사실은 내부적으로 차이가 있다.
리터럴로 선언된 String 클래스는 선언 시 객체가 String constant pool에 생성 되지만
new 를 사용한 선언은 객체가 Heap 영역에 생성된다.
아까 위에서 설명한 String 클래스의 두가지의 특징도 이와 관련이 있다.
우선, 다음 그림을 보자.
s1과 s2처럼 String 객체를 리터럴로 생성하면, 먼저 String contant pool에 같은 값이 있는지 확인한다.
(이후부터는 String pool로 작성하겠다.)
만약 존재한다면, 그 주소값을 리턴하고 없다면 새로운 객체를 생성하여 String pool에 할당한 뒤, 그 주소값을 리턴한다.
그러므로 s1은 새로운 객체를 생성해서 주소값을 리턴받고 s2는 그 이후에 선언 되었으므로 같은 값인 s1의 주소값을 리턴받게 되는 것이다.
s3 같은 경우에는 리터럴로 생성했지만, "Good" 이라는 값이 존재하는 String pool이 없으므로 새로 생성하였다.
s4는 new 를 사용하여 선언하였는데, 이럴 경우엔 String pool이 아닌 Heap 영역에 생성하고 그 주소값을 리턴한다.
만약 s5 라는 것도 s4와 값이 동일하게 new 선언을 할 경우 주소값은 다르다.
서로 각자 Heap 영역에 생성하기 때문!
이젠 String 클래스의 특징과 선언에 대해서는 이해가 되었을 것이다.
그렇다면 직접 보기전까지는 믿지 못하니, 직접 코드와 출력결과를 확인해보자.
< 코드 >
public class Test {
public static void main(String[] args) {
String s1= "Hello";
String s2= "Hello";
String s3= "Good";
String s4 = new String("Hello");
System.out.println("s1==s2: " + (s1==s2));
System.out.println("s1==s3: " + (s1==s3));
System.out.println("s1==s4: " + (s1==s3));
System.out.println("s1.equals(s4): " + s1.equals(s4));
}
}
< 결과 >
== 와 equals 차이점
== : 객체의 주소를 비교
equals : 객체 안의 데이터를 비교
위 예제를 보면, s1 == s2 값은 true가 나오는 것을 볼 수 있다.
== 는 주소 값을 비교하는 것이기 때문에, 같은 String pool 을 공유함으로써 같은 주소값을 쓰고 있다.
즉, true가 리턴된다.
s1 == s3 값은 당연히 데이터가 다르니, 주소 값도(다른 String pool) 달라 false 리턴된다.
s1 == s4 는 데이터는 서로 같으나, s1는 String pool에 s4는 new 로 선언했기 때문에 Heap 영역에 생성되었기 때문에 서로 다른 주소값을 가진다. 즉, false를 리턴한다.
s1.equals(s4) 비교는 s1과 s4의 데이터가 서로 같냐는 비교이다.
주소값은 서로 다르지만 서로 같은 "hello" 데이터를 담고 있기 때문에 같은 데이터를 가지고 있다고 할 수 있다.
즉, true를 반환한다.
String 클래스 메서드
자바의 String 클래스는 문자열을 조작할 수 있는 유용한 메서드들을 가지고 있다.
그 중 유용하고 자주 사용되는 몇 가지 메서드들을 알아보도록 하자
리턴 타입 | 메서드 이름(매개 변수) | 설명 |
char | charAt(int index) | 특정 위치의 문자를 리턴합니다. |
boolean | equals(Object anObject) | 두 문자열을 비교합니다. |
int | length() | 총 문자의 수를 리턴합니다. |
String | replace(CharSequence target, CharSequence replacement) | target 부분을 replacement로 대치한 새로운 문자열을 리턴합니다. |
String | substring(int beginIndex) | beginIndex 위치에서 끝까지 잘라낸 새로운 문자열을 리턴합니다. |
String | substring(int beginIndex, int endIndex) | beginIndex 위치에서 endIndex 전까지 잘라낸 새로운 문자열을 리턴합니다. |
String | toLowerCase() | 알파벳 소문자로 변환한 새로운 문자열을 리턴합니다. |
String | toUpperCase() | 알파벳 대문자로 변환한 새로운 문자열을 리턴합니다. |
String | trim() | 앞뒤 공백을 제거한 새로운 문자열을 리턴합니다. |
String | valueOf(int i) valueOf(double d) |
기본 타입 값을 문자열로 리턴합니다. |
- charAt(int index) - 문자 추출
charAt() 메서드는 매개값으로 주어진 인덱스의 문자를 리턴합니다.
String str = "안녕하세요";
char charValue = str.charAt(0); //결과값 "안"
- equals(Object anObject) - 문자열 비교
기본적으로 문자열 자체(=데이터)를 비교할 때 사용합니다.
String str1 = "hello";
String str2 = "good";
String str3 = new String("hello");
str1.equals(str2); //false
str1.equals(str3); //true
- length() - 문자열 길이
length() 메서드는 문자열의 길이(문자의 수)를 리턴합니다.
문자열 길이는 공백을 포함합니다.
String str = "Hello World!";
int length = str.length(); // 결과: 12
- replace(CharSequence target, CharSequence replacement) - 문자열 대치
replace() 메서드는 첫 번째 매개값인 문자열을 찾아 두 번째 매개값인 문자열로 대치한 새로운 문자열을 생성 후 리턴한다.
String old = "Hello World!";
String new = old.replace("Hello", "안녕"); //결과 : "안녕 Wolrd!"
- substring(int beginIndex), substring(int beginIndex, int endIndex) - 문자열 잘라내기
substring() 메서드는 주어진 인덱스에서 문자열을 추출합니다.
substring() 메서드는 매개값의 개수에 따라 두 가지 형태로 사용됩니다.
String number = "010-9999-8888";
String firstNum = number.substring(4,7); // 9999
String lastNum = number.substring(9); // 8888
- toLowerCase(), toUpperCase() - 알파벳 소/대문자 변경
toLowerCase() 메서드는 문자열을 모두 소문자로 바꾼 새로운 문자열을 생성한 후 리턴합니다.
반대로 toUpperCase() 메서드는 문자열을 모두 대문자로 바꾼 새로운 문자열을 생성한 후 리턴합니다.
String str = "Hello World";
String lower = str.toLowerCase(); // "hello world"
String upper = str.toUpperCase(); // "HELLO WORLD"
- trim() - 앞 뒤 공백 잘라내기
trim() 메서드는 문자열의 앞 뒤 공백을 제거한 새로운 문자열을 생성하고 리턴합니다.
trim() 메서드는 앞 뒤의 공백만 제거할 뿐 중간의 공백은 제거하지 않습니다.
String str = " Hello World! ";
String trimStr = str.trim(); // "Hello World!"
- valueOf(...) - 문자열 변환
valueOf() 메서드는 기본 타입의 값을 문자열로 변환하는 기능을 가지고 있습니다.
boolean, char, int, long, double, float 등 가능합니다.
valueOf() 메서드는 타입별로 static 메서드로 오버로딩이 되어있어 클래스 이름을 붙여주고 사용해야 합니다.
String intNum = String.valueOf(1); //문자열 "1" 로 변환
String doubleNum = String.valueOf(1.5); //문자열 "1.5"로 변환
참고(출처)
https://hyunki99.tistory.com/4
https://velog.io/@donglee99/JAVA-String-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%A0%95%EB%A6%AC
'JAVA' 카테고리의 다른 글
[JAVA] 인터페이스(Interface) 핵심 이해하기 (1) | 2024.03.18 |
---|---|
[JAVA] 추상 클래스(Abstract) 완벽 이해하기 (0) | 2024.03.18 |
[JAVA] 제네릭(Generic) 개념 이해하기 (0) | 2024.03.16 |
[JAVA] 자바 컬렉션(Collection) - List, Map, Set (0) | 2024.03.16 |
[JAVA] 오버로딩과 오버라이딩의 차이점 (0) | 2024.03.16 |
- Total
- Today
- Yesterday
- Overloding
- 인터페이스
- 네이버지도크롤링
- 자바
- redirectattribute
- 타임리프 기본기능
- 빈생명주기콜백
- 스프링http
- 스프링 컨테이너
- 요청데이터
- 객체지향설계원칙
- 크롤링
- HTTP요청
- 스프링특징
- Java
- erd툴
- 추상클래스
- 타임리프
- Servlet
- HttpServletRequest
- 인식안됨
- 인터페이스 추상클래스 비교
- erd editor
- 요청매핑
- Thymeleaf
- RequiredArgsConstruct
- Spring
- 스프링
- 인터페이스 추상클래스 차이
- 스프링 빈
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |