✔ 메소드 오버로딩
메소드 오버로딩의 조건
- 호출할 메소드를 찾을 때는 메소드의 이름과 메소드의 매개변수 정보를 참조하여 메소드를 찾게 됨
- 그러므로 한 클래스 내에 동일한 이름의 메소드를 둘 이상 정의하는 것을 옳지 않지만, 매개변수의 선언이 다르면 가능함
- 이렇게 매개변수의 선언이 다르면 동일한 이름의 메소드 정의를 허용하는 것을 메소드 오버로딩이라 함
- 구체적으로는 매개변수의 수 또는 형이 달라야 함
void simpleMethod(int n) { ... }
void simpleMethod(int n1, int n2) { ... }
void simpleMethod(double d) { ... }
- 오버로딩 된 메소드를 호출할 때에는 전달인자의 자료형과 매개변수의 자료형을 일치시키는 것이 좋음
- 만약 관련 인자를 전달받는 메소드가 정의되어 있지 않다면,
자동 형 변환 규칙이 적용되어 가장 가까운 위치에 놓여있는 자료형으로 형 변환을 우선 시도하게 됨
- 그러므로 애매한 상황을 만들지 않는 것이 좋음
생성자 오버로딩
- 생성자도 매개변수의 선언이 다르면 오버로딩을 통해 둘 이상 정의가 가능함
class Person {
private int regiNum;
private int passNum;
Person(int rnum, int pnum) {
regiNum = rnum;
passNum = pnum;
}
Person(int rnum) {
regiNum = rnum;
passNum = 0;
}
}
키워드 this를 이용한 다른 생성자의 호출
- this를 통해 오버로딩 된 다른 생성자를 호출하여 초기화할 값을 전달받는 역할만 하고,
실제 초기화는 첫 번째로 정의된 생성자를 통해 진행할 수 있음
- 중복된 코드의 수를 줄이는 효과를 얻을 수 있음
class Person {
private int regiNum;
private int passNum;
Person(int rnum, int pnum) {
regiNum = rnum;
passNum = pnum;
}
Person(int rnum) {
this(rnum, 0);
}
}
키워드 this를 이용한 인스턴스 변수의 접근
- this는 생성자 호출 말고 다른 의미로도 사용됨
- 매개변수의 이름이 인스턴스 변수의 이름과 동일하게 선언된 경우, 선언된 지역 내에서의 해당 이름은 매개변수를 의미함
- 그러므로 키워드 this를 이용해야만 이 영역 안에서도 인스턴스 변수에 접근할 수 있게 됨
class SimpleBox {
private int data;
SimpleBox(int data) {
this.data = data;
}
}
✔ String 클래스
문자열 표현을 위한 String 인스턴스의 생성 방법
- 일반적인 인스턴스의 생성 방법과 차이가 없음
- 이 외로도 new를 이용한 방법보다 보편적인 String 인스턴스의 생성 방법도 존재
- 이는 큰따옴표로 표현된 문자열을 대상으로 String 인스턴스가 만들어지고,
이 인스턴스의 참조 값이 문자열 선언을 대신하게 되므로 문자열을 인자로 전달받을 수 있게 됨
String str = new String("Simple String");
String str = "Simple String";
- 하지만 이 둘을 가지고 참조변수를 대상으로 한 == 연산을 하게 될 경우,
'참조변수의 참조 값'에 대한 비교 연산을 진행하게 되며 다른 결과값을 가지게 됨
- String 인스턴스는 Immunable 인스턴스이므로 인스턴스가 갖는 문자열 내용을 변경할 수 없음
- 그러므로 new를 사용하지 않고 String 인스턴스를 생성할 때 문자열 내용이 같을 경우,
하나의 인스턴스를 생성해서 이를 공유하는 방식으로 코드를 처리하게 됨
// 같은 인스턴스
String str1 = "Simple String";
String str2 = "Simple String";
// 서로 다른 인스턴스
String str3 = new String("Simple String");
String str4 = new String("Simple String");
String 인스턴스를 이용한 switch문의 구성
- String 인스턴스를 이용해 switch문을 구성할 수 있음
✔ String 클래스의 메소드
문자열 연결시키기
- 두 문자열을 연결시킨 문자열을 결과로 얻을 수 있음
- 새로운 문자열은 String 인스턴스의 형태로 만들어지고, 만들어진 인스턴스의 참조 값이 반환됨
- concat 메소드는 이어서 호출이 가능함
public String concat(String str)
String1.concat(String2);
문자열의 일부를 추출하기
- 문자열의 뒷부분을 별도의 문자열로 추출할 수 있음
- 새로운 문자열은 String 인스턴스의 형태로 만들어지고, 만들어진 인스턴스의 참조 값이 반환됨
public String substring(int beginIndex)
public String substring(int beginIndex, int endIndex)
String str = "abcdefg";
str.substring(2);
str.substring(2, 4);
문자열의 내용 비교
- 두 개의 String 인스턴스가 지니는 문자열의 내용을 비교할 수 있음
- 두 인스턴스가 지니는 문자열이 같으면 true, 다르면 false를 반환함
public boolean equals(Object object)
String str = "my house";
boolean isSame = str.equals("my house");
- 두 문자열의 내용 비교를 사전 편찬 순서를 기준으로 조금 더 구체적으로 진행하고 싶다면 compareTo 메소드를 고려
- 두 문자열의 내용이 일치하면 0을 반환
- 호출된 인스턴스의 문자열이 인자로 전달된 문자열보다 앞서면 0보다 작은 값 반환
- 호출된 인스턴스의 문자열이 인자로 전달된 문자열보다 뒤서면 0보다 큰 값 반환
public int compareTo(String anotherString)
- 문자열 비교에 있어서 대소문자도 구분하지 않기를 원한다면 compareToIgnoreCase 메소드를 고려
- 사전 편찬 순서상 대문자는 소문자보다 앞에 위치
public int compareToIgnoreCase(String str)
기본 자료형의 값을 문자열로 바꾸기
static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(double d)
static String valueOf(float f)
static String valueOf(int i)
static String valueOf(long l)
double e = 2.718281;
String se = String.valueOf(e);
문자열을 대상으로 하는 + 연산과 += 연산
- 문자열 대상의 + 연산이 가능한 이유는 컴파일러에 의해서 + 연산이 concat 메소드의 호출로 바뀌기 때문임
System.out.println("funny" + "camp");
System.out.println("funny".concat("camp"));
String str = "funny";
str += "camp";
// str = str + "camp";
// str = str.concat("camp");
문자열 결합의 최적화
- valueOf 메소드의 호출을 통해 기본 자료형의 값을 문자열로 변환하는 일은 과도한 String 인스턴스를 생성하므로
컴파일러는 이를 해결하기 위해 StringBuilder라는 클래스를 사용하여 기본 자료형의 값을 문자열로 반환하지 않도록 함
String birth = "<양>" + 7 + '.' + 16;
String birth = "<양>".concat(String.valueOf(7)).concat(String.valueOf('.')).concat(String.valueOf(16));
String birth = (new StringBuilder("<양>").append(7).append('.').append(16)).toString();
StringBuilder 클래스
- StringBuilder 클래스는 내부적으로 문자열을 저장하기 위한 메모리 공간을 지님
- 이러한 메모리 공간은 String 클래스의 메모리 공간과 달리 문자를 추가하거나 삭제하는 것이 가능함
- 따라서 수정하면서 유지해야 할 문자열이 있다면 이 클래스에 내용을 담아서 관리하는 것이 효율적
- StringBuilder 클래스는 문자열에 내용을 더하는 메소드 뿐만 아니라 내용의 일부를 수정 및 삭제하는 메소드도 존재
- 기본 자료형 데이터를 문자열 내용에 추가하는 append 메소드
- 인덱스 start에서부터 end 이전까지의 내용을 삭제하는 delete 메소드
- 인덱스 offset의 위치에 str에 전달된 문자열을 추가하는 insert 메소드
- 인덱스 start에서부터 end 이전까지의 내용을 str의 문자열로 대체하는 replace 메소드
- 저장된 문자열의 내용을 뒤집는 reverse 메소드
- 인덱스 start에서부터 end 이전까지의 내용만 담는 String 인스턴스를 생성하고 반환하는 substring 메소드
- 저장된 문자열의 내용을 담은 String 인스턴스를 생성하고 반환하는 toString 메소드
- StringBuilder 인스턴스 내부에는 문자열 관리를 위한 메모리 공간이 존재하며, 이 공간의 크기를 지정해줄 수 있음
- 물론 메모리 공간을 스스로 관리하고 부족하면 공간을 늘리지만, 이는 소모가 많은 작업임
- 그러므로 사용 계획에 따라 적절한 크기를 초기에 만들어 성능 향상을 기대할 수 있음
StringBuilder stbuf = new StringBuilder(64);
- 이러한 StringBuilder 클래스는 호출된 인스턴스의 참조 값을 반환하게 되므로
메소드를 이어서 호출을 했을 때, 새로운 인스턴스를 생성하는 것이 아니라
한 인스턴스의 메소드를 이어서 호출하는 결과를 갖게 되므로 과도한 String 인스턴스의 생성을 막을 수 있게 됨
StringBuffer 클래스
- StringBuilder 클래스 이전에는 StringBuffer 클래스가 사용되었음
- 생성자를 포함한 멧드의 수, 메소드의 기능, 메소드의 이름과 매개변수의 선언이 모두 동일하였음
- 하지만 StringBuffer는 쓰레드에 안전하지만, StringBuilder는 쓰레드에 안전하지 않음
- 대신 StringBuffer는 속도가 느려지는 단점이 존재함
- 따라서 쓰레드 안전성이 불필요한 상황에서는 성능 향상을 위해 StringBuilder 사용