// Object 클래스 - 1&2&3
| Object 클래스
모든 클래스의 최상위 클래스
java.lang.Object 클래스
모든 클래스는 Object 클래스에서 상속 받음
모든 클래스는 Object 클래스의 메서드를 사용할 수 있음
모든 클래스는 Object 클래스의 일부 메서드를 재정의 하여 사용할 수 있음
java lang 패키지는 import하지 않아도 컴파일러가 자동으로 함
/// ToStringTest.java ///
package object;
class Book
{
String title;
String author;
public Book(String title, String author)
{
this.title = title;
this.author = author;
}
@override
public String toString()
{
// return.super.toString();
// 원형
return author + “,” + tiltle;
// 출력 : 박경리, 토지
}
// Object 클래스의 toString()을 오버라이드 하는 것
}
public class ToStringTest
{
public static void main(String[] args)
{
Book book = new Book(“토지”, “박경리”)
System.out.println(book)
// 출력 : object.Book@15db9742
String str = new String(“토지”);
System.out.println(str);
// 출력 : 토지 > String 클래스는 JDK 클래스라서 toString() 메서드가 불림
// toString() : 어떤 객체의 정보를 String 형태로 출력할 때 호출되는
}
}
!!!
| toString() 메서드
toString() 메서드의 원형
getClass( ).getName( ) + ‘@’ + Integer.toHexString(hashCode( )) |
객체의 정보를 String으로 바꾸어 사용할 때 유용함
자바 클래스중에는 이미 정의된 클래스가 많음
예 : String, Integer, Calendar 등
많은 클래스에서 재정의하여 사용
| equals() 메서드
두 객체의 동일함을 논리적으로 재정의 할 수 있음
물리적 동일함 : 같은 주소를 가지는 객체 ( 같은 메모리 공간 )
논리적 동일함 : 같은 학번의 학생, 같은 주문 번호의 주문
물리적으로 다른 메모리에 위치한 객체라도
논리적으로 동일함을 구현하기 위해 사용하는 메서드
Student studentLee = new Student(100, “이상원"); Student studentLee2 = studentLee; Student studentSang = new Student(100,”이상원"); |
힙 메모리 | ||
studentLee | > | studentId ; 100 studentName : 이상원 |
studentLee2 | ↗ | |
studentSang | > | studentId ; 100 studentName : 이상원 |
물리적으로 다른 위치에 있지만,
논리적으로는 같은 학생임을 구현해야 함
| hashCode() 메서드
hashCode() 메서드의 반환 값 : 인스턴스가 저장된 가상머신의 주소를 10진수로 변환
두 개의 서로 다른 메모리에 위치한 인스턴스가 동일하다는 것은?
논리적으로 동일 : equals()의 반환값이 true
동일한 hashCode 값을 가짐 : hashCode()의 반환 값이 동일
/// EqualsTest.java ///
package object;
public class EqualsTest
{
class Student
{
int studentNum;
String studnetName;
public Student(int studentNum, String studentName)
{
this.studentNum = studentNum;
this.studentName = studentName;
}
public boolean equals(Object obj)
{
if ( obj instanceof Student )
{
Student std = (Student) obj;
return( this.studnetName == std.studentNum );
}
return false;
}
@Override
public int hashCode()
{
return studentNum;
}
}
public static void main(String[] args)
{
// 1번 예제
String str1 = new String(“abc”);
String str2 = new String(“abc”);
System.out.println(str1==str2);
/// 출력 : false / 메모리가 같은지를 물어보기 때문에
System.out.println(str1.equals(str2));
/// 출력 : true /// 오버라이드 하게되면, 각 클래스에 맞게 재정의된다
// 2번 예제
Student lee = new Student(100, “이순신");
Student lee2 = lee
Student Shin = new Student(100, “이순신")
System.out.println(lee.equals(Shin));
/// 출력 : False / 위 1번 예제랑 다르게 String 같은 객체 타입이
/// 아니라 Student로 선언했기 때문에 False가 나오고,
/// 직접 equals를 재정의 해주어야 한다
System.out.println(lee.hashCode());
System.out.println(Shin.hashCode());
// 3번 예제
Integer i1 = 100;
Integer i2 = 100;
/// 출력 : true
Integer i1 = new Integer(100);
Integer i2 = new Integer(100);
/// new Integer을 추가해도 마찬가지로 ture
System.out.println(i1.equals(i2));
System.out.println(i1.hashCode());
System.out.println(i2.hashCode());
// hashCode
System.out.println(System.identityHashcode(i1));
System.out.println(System.identityHashcode(i2));
// 진짜 메모리 주소를 알려고하면 쓰는 메서드
}
}
| clone() 메서드
객체의 복사본을 만듦
기본 틀(prototype)으로 부터 같은 속성 값을 가진 객체의 복사본을 생성할 수 있음
객체지향 프로그래밍의 정보은닉에 위배되는 가능성이 있으므로
복제할 객체는 cloneable 인터페이스를 명시해야 함(=마크업 인터페이스)
( 메서드를 무작정 오버라이드 한다고 되는 것이 아님 )
/// ToStringTest.java 중 일부 ///
package object;
class Book implements Cloneable
{
String title;
String author;
public Book(String title, String author)
{
this.title = title;
this.author = author;
}
@override
public String toString()
{
return author + “,” + tiltle;
}
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
public class ToStringTest
{
public static void main(String[] args)
{
Book book = new Book(“토지”, “박경리”)
System.out.println(book)
Book book2 = (Book)book.clone();
System.out.println(book2);
}
}
/
| finalize() 메서드
설명을 안했다.
이 메서드는 직접 부르는 메서드가 아니다.
객체가 힙 메모리에서 해제될 때 가비지 컬렉터에서 호출되는 메서드이다
주로 하는 것 : 리소스의 해제, 안 닫혔을 소켓을 닫는 것들이나
—----------------—----------------—----------------—----------------—----------------—----------------—------
—----------------—----------------—----------------—----------------—----------------—----------------—------
String, Wrapper 클래스
| String 클래스
String 클래스 선언하기
String str1 = new String(“abc”); // 인스턴스로 생성됨
String str2 = “abc”; // 상수풀에 있는 문자열을 가리킴
str1 | > | 힙 메모리 “abc” |
str2 | ↘ | |
str3 | > | 상수 풀 “test” |
| String은 immutable
한번 선언되거나 생성된 문자열을 변경할 수 없음
String 클래스의 concat() 메서드 혹은 “+”를 이용하여
String을 연결하는 경우 문자열은 새로 생성 됨
javaStr | –x–> | “java” |
(새로 생성된 문자열 가리킴 =) | ↘ “ | “javaandroid” |
androidStr | > | “android” |
| StringBuilder 와 StringBuffer
가변적인 char[] 배열을 멤버변수로 가지고 있는 클래스
문자열을 변경하거나 연결하는 경우 사용하면 편리한 클래스
StringBuffer는 멀티 스레드 프로그래밍에서 동기화가 보장됨
단일 스레드 프로그래밍에서는 StringBuilder를 사용하는 것이 더 좋음
toString() 메서드로 String 반환
| Wrapper 클래스
기본 자료형에 대한 클래스 (Primitive)
기본형 | Wrapper 클래스 |
boolean | Boolean |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
/// StringTest.java ///
package string;
public class StringTest
{
public static void main(String[] args)
{
// 예제 1
String str1 = new String(“abc”);
String str2 = “abc”;
System.out.println(str1 == str2);
// 출력 false / 위는 힙 메모리에 새로운 주소 할당,
// 아래는 상수 풀이기 때문에 다른 주소
String str3 = “abc”;
String str4 = “abc”;
System.out.println(str3 == str4);
// 출력 : true / 상수 풀에서 가져오기 때문에 같은 주소
}
}
/// StringTest2.java ///
package string;
public class StringTest
{
public static void main(String[] args)
{
// 예제 2
String java = new String(“java”);
String android = new String(“android”);
System.out.println(System.identityHashCode(java));
// 출력 : A난수 (String java에 할당된 메모리 주소)
java.concat(android);
System.out.println(java);
// 출력 : javaandroid / 문자는 합쳐져서 출력되나
System.out.println(System.identityHashCode(java));
// 출력 : B난수 ( concat()메서드로
두 String을 연결하면서 새로운 메모리 주소를 할당
}
}
/// StringBuilderTest.java ///
package string;
public class StringBuilderTest
{
public static void main(String[] args)
{
String java = new String(“java”);
String android = new String(“android”);
StringBuilder buffer = new StringBuilder(java);
System.out.println(System.identityHashCode(buffer))
// 출력 : A난수 ( buffer에 할당된 메모리 주소)
buffer.append(“android”);
System.out.println(System.identityHashCode(buffer))
// 출력 : A난수 ( buffer에 할당된 메모리 주소) / 이렇듯 메모리 주소 그대로
java = buffer.toString();
// 최종적으로 문자열로 리턴
}
}
—----------------—----------------—----------------—----------------—----------------—----------------—------—----------------—----------------—----------------—----------------—----------------—----------------—------
Class 클래스
| Class 클래스
자바의 모든 클래스와 인터페이스는 컴파일 후 class 파일로 생성됨
class 파일에는 객체의 정보 ( 멤버변수, 메서드, 생성자등 ) 가 포함되어 있음
Class 클래스는 컴파일된 class 파일에서 객체의 정보를 가져올 수 있음
| Class 클래스 가져오기
String s = new String();
Class c = s.getClass();
Class c = String.Class;
Class c = Class.forName(“java.lang.String”); // 동적 로딩
| reflection 프로그래밍
Class 클래스로부터 객체의 정보를 가져와 프로그래밍 하는 방식
로컬에 객체가 없고 자료형을 알 수 없는 경우 유용한 프로그래밍
java.lang.reflect 패키지에 있는 클래스 활용
| newInstance() 메서드
Class 클래스 메서드
new 키워드를 사용하지 않고 인스턴스를 생성
디폴트 생성자를 생성
| forName() 메서드와 동적 로딩
Class 클래스 static 메서드
동적 로딩이란?
컴파일 시에 데이터 타입이 모두 binding 되어 자료형이 로딩되는 것
(static loding_정적 로딩)이 아니라 실행 중에
데이터 타입을 알고 binding 되는 방식
실행 시에 로딩되므로 경우에 따라 다른 클래스가 사용될 수 있어 유용함
컴파일 타임에 체크할 수 없으므로 해당 문자열에 대한
클래스가 없는 경우 예외(ClassNotFoundException)이 발생할 수 있음
/// StringClassTest.java ///
package classex;
public class StringClassTest
{
public static void main(String[] args) throws ClassNotFoundException
{
/// 예제 1 : 가져오는 방법들
Class c1 = String.class;
String str = new String();
Class c2 = str.getClass();
Class c3 = Class.forName(“java.lang.String”);
/// 예제 2 : 동적 로딩으로 가져온 것으로
Class c3 = Class.forName(“java.lang.String”);
/// array 안에 있는 모든 Constructor 확인
Constructor[] cons = c3.getConstructor();
for(Constructor con : cons)
{
System.out.println(con);
}
/// array 안에 있는 모든 Metho 확인
Method[] methods = c3.getMethods();
for(Method method : methods )
{
System.out.println(method);
}
}
}
/// Person.java ///
package classex;
public class Person
{
private String name;
private int age;
public Person() [];
public Person(String name)
{
}
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public String setName(String name)
{
this.name = name;
}
public String getAge()
{
return age;
}
public String setAge()
{
this.age = age;
}
public String toString()
{
return name;
}
}
/// ClassTest.java ///
package classex;
public class ClassTest
{
public static void main(String[] args)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException, NoSuchMethodException, SecurityException
{
Person person = new Person(“James”);
System.out.println(person);
// newInstance() 가 호출하는 것은 Person 디폴트 생성자를 호출
Class c1 = Class.forName(“classex.Person”);
Person person1 = (Person)c1.newInstance();
System.out.println(person1);
// 출력 : null (= 디폴트 생성자이기 때문에)
// 매개변수가 있는 생성자를 호출
Class[] parameterTypes = {String.class};
Constructor cons = c1.getConstructor(parameterTypes);
Object[] initagrs = {“이순신"};
Person personLee = (Person)cons.newInstance(initagrs);
}
}
—----------------—----------------—----------------—----------------—----------------—----------------—------
—----------------—----------------—----------------—----------------—----------------—----------------—------
| 코딩해 보세요
날짜를 구현한 클래스 MyDate이 있습니다
날짜가 같으면 equals() 메서드의 결과가 true가 되도록 구현해보기
hashCode() 메서드도 구현해본다
—----------------—----------------—----------------—----------------—----------------—----------------—------
—----------------—----------------—----------------—----------------—----------------—----------------—------
이 정리 내용은 패스트 캠퍼스, K-Digital Credit Java 강의를 참고했습니다
'[Programming] > [Language]' 카테고리의 다른 글
[Java] Ch11. 컬렉션 프레임 워크 / 객체 지향 프로그래밍 중급 / K-Digital Credit Java / Summary (0) | 2022.05.25 |
---|---|
[Java] 디폴트 메서드 (Default Method) (1) | 2022.05.02 |
[Java] Ch9. 인터페이스 / K-Digital Credit Java / 객체 지향 프로그래밍 중급 / Summary (0) | 2022.03.29 |
[Java] Ch8. 추상 클래스 / K-Digital Credit Java / 객체 지향 프로그래밍 기초 / Summary (0) | 2022.03.19 |
[Java] Ch7. 상속과 다형성 / K-Digital Credit Java / 객체 지향 프로그래밍 기초 / Summary (0) | 2022.03.19 |