반응형
1. Object 클래스 - 모든 클래스의 최상위 클래스
java.lang 패키지
- 프로그래밍시 import하지 않아도 자동으로 import 된다
- import java.lang.*;
- 많이 사용하는 기본 클래스들이 속한 패키지
- String, Integer, System ...~
모든 클래스는 Object 클래스를 상속 받는다
- java.lang.Object 클래스
- 모든 클래스는 Object에서 상속받고, Object 클래스의 메서드 중 일부는 재정의해서 사용할 수 있음
- 컴파일러가 자동으로 extends Object를 추가함
class Student >> class Student extends Object
toString() 메서드
- 객체의 정보를 String으로 바꿔서 사용할 때 쓰인다
- String이나 Integer 클래스는 이미 재정의 되어 있음
- toString()메서드 재정의 예
class Book {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
@Override
public String toString() {
return title + "," + author;
}
}
public class BookTest {
public static void main(String[] args) {
Book book = new Book("데미안", "헤르만 헤세");
System.out.println(book.toString());
String str = new String("test");
System.out.println(str);
}
}
2. Objecrt 클래스의 메서드 활용
equals() 메서드
- 두 인스턴스의 주소 값을 비교하여 true/false 반환
- 재정의 하여 두 인스턴스가 논리적으로 동일함의 여부를 구현
- 인스턴스가 다르더라도 논리적으로 동일할 경우 true를 반환하도록 재정의 할 수 있음
(같은 학번, 같은 사번, 같은 아이디의 회원 ~ )
hashCode() 메서드
- hashCode()는 인스턴스의 저장 주소를 반환
- 힙 메모리에 인스턴스가 저장되는 방식이 hash방식
- hash : 정보를 저장, 검색하는 자료구조
- 자료의 특정 값(key 값)에 대한 저장 위치를 반환해주는 해쉬 함수를 사용
- 두 인스턴스가 같다는 것은?
- 두 인스턴스에 대한 equals()의 반환 값이 true 동일한 hashCode() 값을 반환
- 논리적으로 동일함을 위해 equals() 메서드를 재정의 하였다면 hashCode()메서드도 재정의 하여 동일한 hashCode 값이 반환되도록 한다
Student.java
public class Student {
private int studentNum;
private String studentName;
public Student (int studentNum, String studentName) {
this.studentNum = studentNum;
this.studentName = studentName;
}
public String toString() {
return studentNum + "," + studentName;
}
@Override
public boolean equals(Object obj) {
if ( obj instanceof Student ) {
Student std = (Student)obj;
if (this.studentNum == std.studentNum)
return true;
else return false;
}
return false;
}
@Override
public int hashCode() {
return studentNum;
}
}
equalsTest.java
public class equalsTest {
public static void main(String[] args) {
Student std1 = new Student(100, "Lee");
Student std2 = new Student(100, "Lee");
// 논리적으로 다름
System.out.println(std1 == std2);
// 논리적으로 다르지만 같은 hash코드값이기 때문에 true 출력
System.out.println(std1.equals(std2));
System.out.println(std1.hashCode());
System.out.println(std2.hashCode());
// 실제 가진 주소
System.out.println(System.identityHashCode(std1));
System.out.println(System.identityHashCode(std2));
}
}
clone() 메서드
- 객체의 원본을 복제하는데 사용하는 메서드
- 생성과정의 복잡한 과정을 반복하지 않고 복제할 수 있음
- clone()메서드를 사용하면 객체의 정보(멤버 변수 값 등등)가 동일한 또 다른 인스턴스가 생성되는 것이므로,
객체 지향 프로그램에서의 정보은닉, 객체 보호의 관점에서 위배될 수 있음 - 해당 클래스의 clone()메서드의 사용을 허용한다는 의미로 cloneable 인터페이스를 명시해 줌
Student.java
public class Student implements Cloneable{
.......
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
EqualTest.java
Student Lee3 = (Student)Lee.clone();
System.out.println(System.identityHashCode(Lee));
System.out.println(System.identityHashCode(Lee3));
3. String, StringBuilder, StringBuffer 클래스, text block
String 클래스
- String 선언하기
String str1 = new String("abc");
String str2 = "abc";
- 힙 메모리에 인스턴스로 생성되는 경우와 상수 풀(constant pool)에 있는 주소를 참조하는 두가지 방법
- 힙 메모리는 생성될 때마다 다른 주소 값을 가지지만, 상수 풀의 문자열은 모두 같은 주소 값을 가짐
public class StringTest {
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2); // false
String str3 = "abc";
String str4 = "abc";
System.out.println(str3 == str4); // true
}
}
- 한번 생성된 String은 불변( immutable )
- String을 연결하면 기존의 String에 연결되는 것이 아닌 새로운 문자열이 생성됨 ( 메모리 낭비가 발생할 수도 )
public class StringTest2 {
public static void main(String[] args) {
String java = new String("java");
String android = new String("android");
java = java.concat(android);
System.out.println(java); // javaandroid
}
}
StringBuilder, StringBuffer 활용하기
- 내부적으로 가변적인 char[]를 멤버 변수로 가짐
- 문자열을 여러번 연결하거나 변경할 때 사용하면 유용함
- 새로운 인스턴스를 생성하지 않고 char[]를 변경함
- StringBuffer는 멀티 쓰레드 프로그래밍에서 동기화 ( synchronization )를 보장
- 단인 쓰레드 프로그램에서는 StringBuilder 사용을 권장
- toString() 메서드로 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)); //주소값 925858445
buffer.append(android);
System.out.println(System.identityHashCode(buffer)); //주소값 925858445
String test = buffer.toString();
System.out.println(test); // javaandroid
}
}
test block 사용하기 ( java 13 )
- 문자열을 """ """ 사이에 이어서 만들 수 있음
- html, json문자열을 만드는데 유용하게 사용할 수 있음
public class StringTextBlock {
public static void main(String[] args) {
String strBlock = """
This is
String
Block
""";
System.out.println(strBlock);
System.out.println(getBlockofHtml());
}
public static String getBlockofHtml() {
return """
<html>
<body>
<span>Test</span>
</body>
</html>
""";
}
}
4. Class 활용하기
Class 클래스
- 자바의 모든 클래스와 인터페이스는 컴파일 후 class파일이 생성됨
- Class 클래스는 컴파일 된 class 파일을 로드하여 객체를 동적 로드하고, 정보를 가져오는 메서드가 제공됨
- Class.forName("클래스 이름") 메서드로 클래스를 동적으로 로드 함
Class c = Class.forName("java.lang.String");
- 클래스 이름으로 직접 Class 클래스 가져오기
Class c = String.class;
- 생성된 인스턴스에서 Class 클래스 가져오기
String s = new Stirng();
Class c = s.getClass(); // Object 메서드
동적 로딩
- 컴파일시 데이터 타입이 binding되는 것이 아닌, 실행(runtime)중에 데이터 타입을 binding하는 방법
- 프로그래밍 시에는 문자열 변수로 처리했다가 런타임시에는 원하는 클래스를 로딩하여 binding할 수 있다는 장점
- 컴파일 시에 타입이 정해지지 않으므로 동적 로딩시 오류가 발생하면 프로그램의 심각한 장애가 발생가능
Class의 newInstance()메서드로 인스턴스 생성
- new 키워드를 사용하지 않고 클래스 정보를 활용하여 인스턴스를 생성할 수 있음
클래스 정보 알아보기
- reflection 프로그래밍 : Class 클래스를 사용하여 클래스의 정보( 생산자, 변수, 메서드 )등을 알 수 있고,
인스턴스를 생성하고, 메서드를 호출하는 방식의 프로그래밍 - 로컬 메모리에 객체가 없는경우, 원격 프로그래밍, 객체의 타입을 알 수 없는 경우에 사용
- java.lang.reflect 패키지에 있는 클래스를 활용하여 프로그래밍
- 일반적으로 자료형을 알고 있는 경우엔 사용하지 않음
StringTest.java
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class StringTest {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("java.lang.String");
Constructor[] cons = c.getConstructors();
for ( Constructor co : cons ) {
System.out.println(co);
}
Method[] m = c.getMethods();
for ( Method mth : m ) {
System.out.println(m);
}
}
}
Person.java
public class Person {
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name;
}
}
ClassTest.java
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ClassTest {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c1 = Class.forName("ch04.Person");
Person person = (Person)c1.newInstance();
person.setName("Lee");
System.out.println(person);
Class c2 = person.getClass();
Person p = (Person)c2.newInstance();
System.out.println(p);
Person kim2 = new Person("Kim",1);
System.out.println(kim2);
// 여기서 에러가 뜨는데 안잡힘 버전 차이인지 셋팅 차이인지 ;;
Class[] parameterTypes = {String.class};
Constructor cons = c2.getConstructor(parameterTypes);
Object[] initargs = {"Kim"};
Person kimPerson = (Person)cons.newInstance(initargs);
System.out.println(kimPerson);
}
}
반응형
'Java' 카테고리의 다른 글
자바와 자료구조 / Generic, T extends, 컬렉션 프레임워크 (0) | 2022.11.30 |
---|---|
자바와 자료구조 / 배열, 스택, 큐 (0) | 2022.11.29 |
Java 객체지향 핵심 / 다운 캐스팅, 추상클래스, 추상클래스 응용, 인터페이스, DAO, 인터페이스 상속 (1) | 2022.11.18 |
Java 객체 지향 핵심 / 상속, 형 변환, 재정의(override), 다형성 (0) | 2022.11.17 |
Java 객체지향 입문 / 배열, 객체 배열, 2차원 배열, ArrayList (0) | 2022.11.16 |