본문 바로가기
JAVA/명품 자바 프로그래밍 6장

명품 자바 프로그래밍 6장 - 모듈,object,Wrapper,String 클래스

by 집돌이디벨로퍼 2023. 9. 26.

앞에서 배운 패키지는 클래스나 인터페이스의 컴파일된 클래스를 한곳에 담는 곳이라면

모듈은 패키지들을 담는 컨테이너라고 생각하면 된다.

모듈들 중에서 꼭 필요한 기본 모듈이 .java.base 모듈인데 java.base.jmod 파일에 들어있다

이 모듈 안에는 자바 응용프로그램에서 가장 많이 사용되는 패키지와 클래스들이 들어있다.

ex) java.util 패키지 , java.math 패키지 등등 

 

Object 클래스

Object 클래스는 아무 클래스도 상속받지 않는 유일한 클래스 => 계층 구조상 최상위 클래스

 

객체를 문자열로 변환 = > toString()메소드

java 에서 제공하는 메소드도 오버라이딩이 가능하다

package apgkw;
class Point{
	private int x,y;
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public String toString() {
		return "Point(" + x + "," + y + ")";  // toString 메소드 오버라이딩
	}
}
public class ToStringEx {
	public static void main(String [] args) {
		Point p = new Point(2,3);
		System.out.println(p.toString());
		System.out.println(p);
		System.out.println(p + "입니다.");
		
	}

}
//결과 값
// Point(2,3)
// Point(2,3)
// Point(2,3)입니다.

 


equals() 메소드 vs == 연산자 비교

 

Point a = new Point(2,3);
Point b = new Point(2,3);
Point c = a;
if(a == b)
System.out.println("a==b"):
if(a == c)
System.out.println("a==c"):
//결과값 a==c

a 레퍼러스 , b 레퍼런스 각각 레퍼런스 값은 같지만 엄연히 분리되었기 때문에 서로다른 객체라고 생각하면 된다

따라서 a == b 의 명제는 거짓이다. 즉, 두 객체의 내용물이 같은지 비교하는 것이 아니라 두 레퍼런스가 동일한 객체를 가리키는지 비교하는 것.

 

반면에 a == c 명제가 참인이유는 레퍼런스 a값을 c에 대입을 해버렸기 때문에 분리된 객체가 아닌 레퍼런스 값을 공유한다.

따라서 레퍼런스 a가 곧 레퍼런스 c 이고 , 레퍼런스 c가 곧 레퍼런스 a이다

이것은 얕은 복사 개념으로 생각하면 될 것이다.

 

□.equals(Object obj)는 인자를 담당하는 객체 obj그 자신을 비교하여 두 객체의 값이 같은지를 비교하는 메소드이다.

String a = new String("Hello");
String b = new String("Hello");
if(a==b) // false
System.out.println("a==b");
if(a.equals(b)) // true
System.out.println("a와 b는 둘 다 Hello입니다.");
//결과값 a와b는 둘다 Hello입니다.

a와 b는 서로 다른객체를 가르킨다 따라서 두 레퍼런스는 서로 다르기때문에 a==b는 거짓이다.

한편, a와 b의 가르키는 문자열 자체는 같기 때문에 레퍼런스의 값만을 비교하는 a.equals(b)는 참이다.

 

예제6-4

class Rect{
	private int width;
	private int height;
	public Rect(int width, int height) {
		this.width=width;
		this.height=height;
	}
	
	public boolean equals(Object obj) { // equals 오버라이딩  --> 사각형 면적 비교하게끔
		Rect p = (Rect)obj; // obj를 Rect로 다운 캐스팅
		if(width*height == p.width*p.height) 
			return true;
		else 
			return false;
	}
}

public class RectEqualsEx {
	public static void main(String[] args) {
		Rect a = new Rect(2,3);
		Rect b = new Rect(3,2);
		Rect c = new Rect(3,4);
		if(a.equals(b))
			System.out.println("a is equals to b");
		if(a.equals(c))
			System.out.println("a is equals to c");
		if(b.equals(c))
			System.out.println("b is equals to c");
	}
}
//결과값 : a is equals to b 
// 면적이 같으므로

Wrapper 메소드

기본 값들을 객체로 만들어서 인식하게 해주는 메소드(모든 클래스가 기본 값들을 다루는 것이 아니기 때문에)

문자열 => 객체

객체 => 문자열 

integer i = Integer.valueOf(10);
Character c = Integer.valueOf('c');
Double d = Double.valueOf(3.14);  
Boolean b = Boolean.valueOf(true);  

Character를 제외한 나머지 경우 문자열로 객체 생성가능
integer i = Integer.valueOf("10");
Double d = Integer.valueOf("3.14");

박싱과 언박싱

박싱 : 기본값 => 객체

언박싱 : 객체 => 기본값

Integer ten = 10; // 자동 박싱, Integer ten = Integer.valueOf(10); 의 의미와 같음
int n = ten; // 자동 언박싱, int n = ten.intValue(); n이 10으로

 

스트링 리터럴 테이블 => 같은 값을 서로 다른 객체가 공유 가능하다.

장점 : 리터럴을 공유하면 스트링을 생성하는 실행시간을 줄일 수 있다.

 

new String()에 의해 생성된 객체는 힙 메모리에 독립적으로 생성된다. 

 

스트링 객체는 일단 생성이되면 수정이 불가능하다.

 

String s = new String("Hello");  
String r = s.concat("Java");  // 스트링 s에 "java"를 덧붙인 새로운 스트링 객체 리턴


// s.concat의 실행결과 스트링 s는 변경되지 않고, Hellowjava를 새로생성

StringBuffer => 배열의 인덱스 느낌으로 문자열을 나타낸다고 생각하면 편함

 

StringBuffer 객체는 String객체와는 반대로 저장된 문자열의 수정이 가능하다

그 이유는 문자열을 저장하는 가변 버퍼를 갖고있기 때문이다 

 

StringBuffer활용

문자열의 길이가 길거나 문자열이 수시로 변하는 경우 StringBuffer 클래스를 이용하는 것이 적합하다.

 

+ 간단한 문자열 처리시 String 클래스 이용.