티스토리 뷰
목차
📍 Object
📍 Object 클래스
– java.lang 패키지에 위치하는 클래스.
– 모든 클래스의 슈퍼클래스 (최상위 클래스)
→ 상속을 표현하지 않으면 자동으로 상속되는 클래스.
– Object 클래스의 모든 멤버는 다른 클래스에서 사용 또는 오버라이딩 가능.
▶ equals( ) 메서드
– public boolean equals(Object o) { }
– 두 객체가 같은지 동등비교(==)를 수행함.
→ 즉, 두 객체의 주소값을 비교하여 같으면 true 다르면 false 리턴.
– 실제 '두 객체가 같다'는 의미는 두 객체의 주소값 비교가 아닌, 객체가 가지는 멤버변수가 같다는 의미로 사용됨.
→ 따라서, 사용자가 정의하는 클래스에 Object 클래스로부터 상속받은 equlas() 메서드를 오버라이딩하여
각 객체의 멤버변수끼리 비교하도록 수정하여 사용함.
– Java에서 제공하는 대부분의 클래스 (API)들은
Object 클래스의 equals() 메서드를 오버라이딩 해 놓았으므로 객체 내용 비교가 가능함.
ex ) String 클래스, ArrayList 클래스 등
– equals() 메서드 자동 생성 (오버라이딩)기능을 활용하여 쉽게 구현 가능.
→ alt + shift + s + h
EX ) |
• Person 클래스 정의
class Person{
String name;
String jumin;
// 파라미터 생성자
public Person(String name, String jumin) {
super();
this.name = name;
this.jumin = jumin;
}
}
• OverridePerson 클래스 정의
– Object 클래스의 equals() 메서드 오버라이딩 함. (alt + shift + s + h)
class OverridePerson{
String name;
String jumin;
// 파라미터 생성자
public OverridePerson(String name, String jumin) {
super();
this.name = name;
this.jumin = jumin;
}
// hashCode() 비교
@Override
public int hashCode() {
return Objects.hash(jumin, name);
}
// equals() 메서드 오버라이딩
// alt + shift + s + h
@Override
public boolean equals(Object obj) {
if (this == obj) // 자기자신 비교 당연히 true
return true;
if (obj == null) // 값이 비어있으면 당연히 false
return false;
if (getClass() != obj.getClass())
return false;
OverridePerson other = (OverridePerson) obj;
return Objects.equals(jumin, other.jumin) && Objects.equals(name, other.name);
}
}
코드 분석
14~17 | ▪ hashCode() 비교 – 같다 아니다를 판단하여 true 같을 경우, equals() 메서드로 가서 다시 비교함. 아니다로 판단될 경우는 바로 false의 값을 리턴함. – 단축키로 equals() 메서드 오버라이딩 시 자동 생성 됨. 이중 비교 느낌이라 사실상 '내용이 같다'를 비교할 때는 굳이 hashcode()까지 필요 없으므로 지워도 무방함. |
21~31 | ▪ equals() 메서드 오버라이딩 – OverridePerson 클래스의 모든 멤버변수를 비교하여 하나라도 다를 경우 false를 리턴, 모두 같을 경우 true를 리턴하도록 수정. |
27 | – getClass()는 클래스의 정보를 받아오는 메서드. ex ) object.Person@1c4af82c |
• main 메서드 / 객체 p1과 p2 비교하기
Person p1 = new Person("홍길동", "901010-1234567");
Person p2 = new Person("홍길동", "901010-1234567");
System.out.println("p1의 객체 정보 : " + p1); // object.Person@5e91993f
System.out.println("p1의 객체 정보 : " + p2); // object.Person@1c4af82c
– 같은 클래스에서 생성한 인스턴스지만 '@' 엣 뒤에 있는 주소값이 다름.
1 ) 동등비교 (==)
if(p1 == p2) {
System.out.println("두 객체의 주소값이 같다 (==)");
}else {
System.out.println("두 객체의 주소값이 다르다 (==)");
}
– 참조변수에 대한 동등비교(==) 수행. 객체 p1과 p2에 저장된 주소값을 비교.
✓ 실행 결과
두 객체의 주소값이 다르다 (==)
2 ) equals() 메서드 비교
if(p1.equals(p2)) {
System.out.println("두 객체의 주소값이 같다 (equals())");
}else {
System.out.println("두 객체의 주소값이 다르다 (equals())");
}
– 참조변수에 대한 Object 클래스의 equals() 메서드를 통한 비교 수행. 객체 p1과 p2에 저장된 주소값을 비교.
→ 동등비교 연산 (==)과 동일한 결과를 수행함.
✓ 실행 결과
두 객체의 주소값이 다르다 (equals())
• Person타입 변수 p3에 변수 p2의 주소값을 복사
Person p3 = p2;
System.out.println("p2의 객체 정보 : " + p2); // object.Person@2c13da15
System.out.println("p3의 객체 정보 : " + p3); // object.Person@2c13da15
– 변수 p2의 주소값을 '복사'하여 변수 p3에 저장한 것이므로 둘은 같은 주소값을 가짐.
1 ) 동등비교 (==)
if(p3 == p2) {
System.out.println("두 객체의 주소값이 같다 (==)");
}else {
System.out.println("두 객체의 주소값이 다르다 (==)");
}
– 참조변수에 대한 동등비교(==) 수행.
– 객체 p1과 p2에 저장된 주소값을 비교.
✓ 실행 결과
두 객체의 주소값이 같다 (==)
2 ) equals() 메서드 비교
if(p3.equals(p2)) {
System.out.println("두 객체의 주소값이 같다 (equals())");
}else {
System.out.println("두 객체의 주소값이 다르다 (equals())");
}
– 참조변수에 대한 Object 클래스의 equals() 메서드를 통한 비교 수행.
– 동등비교 연산(==)과 동일한 결과를 수행
✓ 실행 결과
두 객체의 주소값이 같다 (equals())
• OverridePerson타입의 객체 p10과 p11의 인스턴스 생성
OverridePerson p10 = new OverridePerson("홍길동", "901010-1234567");
OverridePerson p11 = new OverridePerson("홍길동", "901010-1234567");
1 ) 동등비교 (==)
if(p10 == p11) {
System.out.println("두 객체의 주소값이 같다 (==)");
}else {
System.out.println("두 객체의 주소값이 다르다 (==)");
}
– 참조변수에 대한 동등비교(==) 수행.
→ 객체 p10과 011에 저장된 주소값을 비교함.
✓ 실행 결과
두 객체의 주소값이 다르다 (==)
2 ) 오버라이딩 된 equals() 메서드
if(p10.equals(p11)) {
System.out.println("두 객체의 내용 (멤버변수 값)이 같다");
}else {
System.out.println("두 객체의 내용 (멤버변수 값)이 다르다");
}
– 두 문자열의 내용을 비교함.
✓ 실행 결과
두 객체의 내용 (멤버변수 값)이 같다
▶ String 객체 (문자열) 생성 방법
1. 리터럴 할당을 통해 생성하는 방법
– 많이 사용하는 방법. (추천)
– 상수풀 (Constant Pool)에서 동일한 문자열이 존재하는지 검사 후,
존재하지 않으면 새로 생산하고 존재하면 해당 주소값을 리턴함.
2. 클래스의 인스턴스로 생성하는 방법
– String도 하나의 클래스이므로 인스턴스를 생성할 수 있음.
→ 리터럴 할당을 통해서도 간단히 생성할 수 있는데 굳이 Heap 영역에 메모리를 할당할 필요 없음.
– 잘 사용하지 않는 방법. 그냥 이렇게도 생성할 수 있다는 것만 알아두기.
EX1 ) 리터럴 할당을 통해 문자열 생성 |
• 문자열 내용도 같고 주소값도 같은 s1, s2 생성
String s1 = "Hello";
String s2 = "Hello";
– 리터럴 할당을 통해 문자열을 생성하여 각각 변수에 저장함.
– 문자열의 내용이 같은 경우, Method 영역의 Constant Pool에 의해 같은 주소값을 갖게됨.
• 동등비교연산자 (==) 사용
if(s1 == s2) {
System.out.println("s1과 s2는 주소값이 같다");
}else {
System.out.println("s1과 s2는 주소값이 다르다");
}
– 동등비교연산자를 사용한 두 문자열의 주소값 비교해보면 같음을 알 수 있음.
✓ 실행 결과
s1과 s2는 주소값이 같다
• String 클래스의 오버라이딩 된 equals() 메서드 사용
if(s1.equals(s2)) {
System.out.println("s1과 s2는 문자열 내용이 같다");
}else {
System.out.println("s1과 s2는 문자열 내용이 다르다");
}
– 두 문자열의 내용 비교
– equals() 메서드로 두 문자열의 내용이 같음을 알 수 있음.
✓ 실행 결과
s1과 s2는 문자열 내용이 같다
EX2 ) 클래스의 인스턴스로 문자열 생성 |
• 문자열 내용은 같고 주소값은 다른 s3, s4 생성
String s3 = new String("Hello");
String s4 = new String("Hello");
– String 클래스의 인스턴스를 각각 새롭게 생성하여 참조변수에 저장했으므로 참조변수 s3와 s4는 다른 주소값을 가짐.
– 생성된 s3와 s4는 문자열 내용은 같지만 주소값이 다름.
• 동등비교연산자 사용
if(s3 ==s4) {
System.out.println("s3과 s4는 주소값이 같다");
}else {
System.out.println("s3과 s4는 주소값이 다르다");
}
✓ 실행 결과
s3과 s4는 주소값이 다르다
• String 클래스의 오버라이딩 된 equals() 메서드 사용
if(s3.equals(s4)) {
System.out.println("s3과 s4는 문자열 내용이 같다");
}else {
System.out.println("s3과 s4는 문자열 내용이 다르다");
}
– 두 문자열의 내용 비교.
✓ 실행 결과
s3과 s4는 문자열 내용이 같다
▶ toString( ) 메서드
– public String toString( ){ }
– 어떤 객체의 정보를 문자열로 변환하여 리턴.
– 기본적으로 Object 클래스의 toString( ) 메서드는 객체의 정보 (주소값)을 문자열로 리턴하도록 정의되어 있음.
– 일반적으로 객체의 정보는 객체 내의 멤버변수에 저장된 데이터 (속성값)를 의미하므로
Object 클래스의 toString() 메서드를 오버라이딩하여 객체가 가진 멤버변수 값을 문자열로 결합 후 리턴해야 함.
– 출력문 내에서는 toString() 메서드 생략 가능. (참조변수명만 사용 가능)
– Java에서 제공하는 대부분의 클래스 (API)들은 toString() 메서드가 오버라이딩 되어 있으므로
객체에 저장된 값을 문자열로 리턴받기 가능.
ex ) String 클래스, ArrayList 클래스 등.
– equals() 메서드와 마찬가지로 단축키를 통한 자동 생성 가능. (alt + shift + s + s)
EX1 ) |
• Person2 클래스 정의
class Person2{
String name;
int age;
String jumin;
// 파라미터 생성자
public Person2(String name, int age, String jumin) {
super();
this.name = name;
this.age = age;
this.jumin = jumin;
}
}
• Person3 클래스 정의 — toString() 메서드 오버라이딩
class Person3{
String name;
int age;
String jumin;
// 파라미터 생성자
public Person3(String name, int age, String jumin) {
super();
this.name = name;
this.age = age;
this.jumin = jumin;
}
// toString() 메서드 오버라이딩
@Override
public String toString() {
return "Person3 [name=" + name + ", age=" + age + ", jumin=" + jumin + "]";
}
}
– 참조변수에 있는 주소값을 출력하는 toString() 메서드를 오버라이딩하여 객체 내용을 출력하게끔 오버라이딩 함.
– 현재 인스턴스가 가진 멤버변수들을 모두 문자열로 결합하여 리턴.
– 결합하는 형태 (출력 모양)는 개발자가 알아서 결정.
• toString() 메서드의 생략
String str = new String("자바"); // String타입도 객체
System.out.println(str);
System.out.println(str.toString());
– 원래라면 str 참조변수 출력 시,
참조변수가 가르키고 있는 객체의 주소값이 출력되어야 하지만 '자바' 라는 문자열이 출력됨.
→ toString() 메서드가 생략되어 있기 때문. (문자열 출력)
✓ 실행 결과
자바
자바
• 출력문 내에 toString() 메서드 호출
Person2 p = new Person2("홍길동", 20, "041010-3123456");
System.out.println("사람 p의 정보 : " + p);
System.out.println("사람 p의 정보 : " + p.toString());
– 참조변수 p를 출력하니 객체의 주소값이 나옴.
– println() 메서드 내에 p 객체 정보 출력시 toString() 생략 가능함을 알 수 있음.
✓ 실행 결과
사람 p의 정보 : object.Person2@512ddf17
사람 p의 정보 : object.Person2@512ddf17
• 출력문이 아닌 결과값을 변수에 저장하는 경우
// String personInfo = p;
String personInfo = p.toString();
– 왼쪽은 String타입, 오른쪽은 Person2타입으로 에러 발생.
→ 반드시 toString() 메서드 필수 입력.
• Object 클래스의 toString() 메서드
System.out.println("Person2 p의 클래스명 : " + p.getClass().getName());
System.out.println("Person2 p의 주소값 : " + p.hashCode());
– "클래스명@주소값" 형태의 문자열 리턴되며, 주소값은 16진수로 변환되어 문자열로 결합됨.
✓ 실행 결과
Person2 p의 클래스명 : object.Person2
Person2 p의 주소값 : 1361960727
• Person3의 인스턴스 생성
Person3 p3 = new Person3("홍길동", 20, "041010-3123456");
System.out.println("p3의 객체의 정보 : " + p3.toString());
System.out.println("p3의 객체의 정보 : " + p3);
– Person3 클래스에서 오버라이딩 한 toString() 메서드 호출함.
– println() 메서드 내에서는 toString() 메서드를 생략해도 결과가 똑같이 출력됨.
✓ 실행 결과
p3의 객체의 정보 : Person3 [name=홍길동, age=20, jumin=041010-3123456]
p3의 객체의 정보 : Person3 [name=홍길동, age=20, jumin=041010-3123456]
EX2 ) |
• Account 클래스 정의
– 계좌번호 (accountNo, 문자열)
– 예금주명 (ownerName, 문자열)
– 현재잔고 (balance, 정수형)
– 생성자에 계좌번호, 예금주명, 현재잔고를 전달받아 초기화.
– equals() 메서드 오버라이딩하여 계좌정보를 비교하도록 정의.
– toString() 메서드 오버라이딩하여 계좌정보를 문자열로 리턴하도록 정의.
class Account{
String accountNo;
String ownerName;
int balance;
// 파라미터 생성자
// alt + shift + s + o
public Account(String accountNo, String ownerName, int balance) {
super();
this.accountNo = accountNo;
this.ownerName = ownerName;
this.balance = balance;
}
// equals() 메서드 오버라이딩
// alt + shift + s + h
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
return Objects.equals(accountNo, other.accountNo) && balance == other.balance
&& Objects.equals(ownerName, other.ownerName);
}
// toString() 메서드 오버라이딩
// alt + shift + s + s
@Override
public String toString() {
return "Account [accountNo=" + accountNo + ", ownerName=" + ownerName + ", balance=" + balance + "]";
}
}
• main 메서드에서 실행
Account acc = new Account("박보검", "3333-01-8413246", 100000000);
System.out.println("acc의 계좌정보 : " + acc);
Account acc2 = new Account("박보굼", "1111-01-8413246", 500000000);
if(acc.equals(acc2)) {
System.out.println("두 계좌는 동일한 계좌입니다.");
}else{
System.out.println("두 계좌는 다른 계좌입니다.");
}
✓ 실행 결과
acc의 계좌정보 : Account [accountNo=박보검, ownerName=3333-01-8413246, balance=100000000]
두 계좌는 다른 계좌입니다.
'JAVA' 카테고리의 다른 글
제네릭 (Generic, 일반화) (0) | 2023.04.14 |
---|---|
Scanner 클래스 (0) | 2023.04.14 |
인터페이스 (Interface) (0) | 2023.04.04 |
상수 (Constant) (0) | 2023.04.04 |
추상메서드와 추상클래스 (Abstract) (0) | 2023.03.29 |
- Total
- Today
- Yesterday
- 매개변수
- model2
- 로컬저장소
- 내장객체
- 주석문
- 문자형
- Git
- Dao
- github
- Method
- 오버라이딩
- DB
- 다형성
- 데이터타입
- Java
- mysql
- 출력문
- 논리형
- 업캐스팅
- gitbash
- null
- JSTL
- javascript
- Object
- 단일행함수
- 제어문
- 원격저장소
- jsp
- 숫자형
- 인자
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |