ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 Object, Class
    언어/Java 2023. 7. 10. 20:01
    728x90
    반응형
    SMALL

    java.lang 패키지

    • import 하지 않아도 자동으로 import 됩니다.
    • 많이 사용하는 기본 클래스들이 포함된 패키지입니다.
    • String, Integer, System, ...

     

    Object 클래스

    • java.lang.Object
    • 모든 클래스는 Object 클래스를 상속 받습니다(모든 클래스의 최상위 클래스). Object 클래스의 메서드 중 일부를 재사용해서 사용할 수 있다.
    • 클래스 선언 시 컴파일러가 자동으로 extends Object를 추가합니다.

     

    toString() 메서드

    • 객체의 정보를 String으로 바꾸어서 사용할 때 쓰입니다.
    • String, Integer 클래스에 이미 재정의 되어 있습니다.
    • 일반 클래스에 재정의해 사용할 경우 System.out.print() 출력 시 해당 리턴 값이 출력됩니다.

     

    class A {
        String a;
        String b;
    
        String toString() {
            return a+" "+b;
        }
    }

     

    equals 메서드

    • 재정의 하지 않을 경우 두 인스턴스의 주소값을 비교하여 boolean 타입을 반환합니다.
    • 재정의 할 경우 두 인스턴스가 논리적으로 동일한지 여부를 구현합니다. (같은 id를 가지고 있는지, 같은 번호를 가지고 있는지, ...)

     

    hashCode() 메서드

    • 인스턴스의 저장 주소를 반환합니다.
    • 힙 메모리에 인스턴스가 저장되는 방식입니다.
    • 자료의 특정 값(키 값)에 대한 저장 위치를 반환해주는 해시 함수를 이용합니다.
    • equals()의 반환 값이 true일 경우 동일한 hashCode() 값을 반환하는 것입니다.
    • equals() 메서드를 논리적 동일할 경우로 재정의 했다면 hashCode() 메서드도 재정의하여 동일한 hashCode 값을 반환하도록 해야합니다.
    class A{
        int code;
    
        @Override
        public boolean equals(Object obj) {
            if( obj instanceof A){
                A a = (A)obj;
                if(a.code == this.code){
                    return true;
                }
            }
            return false;
        }
    
        @Override
        public int hashCode() {
            return code;
        }
    }

     

    clone 메서드

    • 객체의 원본을 복제하는데 사용하는 메서드 (두 인스턴스의 실제 hashcode값은 다릅니다. -> 다른 인스턴스지만 객체의 정보는 모두 같습니다)
    • clone() 메서드를 사용하면 객체의 정보(멤버 변수 값 등)가 동일한 또 다른 인스턴스가 생성되는 것이므로, 객체 지향 프로그래밍에서의 정보 은닉, 객체 보호의 관점에서 위배될 수 있습니다.
    • 해당 클래스의 clone() 메서드의 사용을 허용하려면 cloneable 인터페이스를 명시해주면 됩니다.

     

    class A implements Cloneable {
        ...
    
        @Overrride
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A();
        A b = (A)a.clone();
    }

     

    clone을 할 경우 exception이 발생할 수 있으므로 예외처리를 해주어야 합니다.

    (clone과 같은 경우 예외 처리와 Cloneable 인터페이스에 대해서 자세하게 살펴보는 것이 좋을 것 같다고 생각이 듭니다.)

     

     

    String 클래스

    • 힙 메모리에 인스턴스로 생성되는 경우 : String str = new String("string");
    • 상수 풀에 있는 주소를 참조 : String str = "string";
    • 힙 메모리는 생성될 때마다 다른 주소값을 가지지만, 상수 풀의 문자열은 모두 같은 주소값을 가집니다.
    String str1 = new String("string");
    String str2 = new String("string");
    
    String str3 = "string";
    String str4 = "string";
    
    System.out.println(str1==str2); //false
    System.out.println(str3==str4); //true

     

    • 한 번 생성된 String은 불변합니다.
    • String을 연결하면 기존의 String에 연결되는 것이 아닌 새로운 문자열이 생성됩니다. ( 메모리 낭비 발생할 수 있다.)

     

    String a = new String("A");
    String b = new String("B");
    
    System.out.println(System.identityHashCode(a)); //1111
    
    a = a.concat(b);
    
    System.out.println(a); // AB
    System.out.println(System.identityHashCode(a)); //1112

     

     

    StringBuilder, StringBuffer

    • 내부적으로 가변적인 char[]를 멤버 변수로 가집니다.
    • 문자열을 여러번 연결하거나 변경할 경우 유용합니다.
    • 문자열 변경 시 새로운 인스턴스를 생성하지 않고 char[]를 변경합니다.
    • StringBuffer는 멀티 쓰레드 프로그래밍에서 동기화를 보장합니다.
    • 단일 쓰레드 프로그램에서는 StringBuilder 사용을 권장합니다.
    • toString() 메서드로 String으로 변환 가능합니다.

     

    Class 클래스

    • 자바의 모든 클래스와 인터페이스는 컴파일 후 class파일이 생성됩니다.
    • Class 클래스는 컴파일 된 class 파일을 로드하여 객체를 동적 로드하고, 정보를 가져오는 메서드가 제공됩니다.
    • Class.forName("<클래스 명>") 메서드로 클래스를 동적으로 로드할 수 있습니다.
    Class c = Class.forName("java.lang.String");
    • 클래스 이름으로 직접 Class 클래스 가져올 수 있습니다.
    Class c = String.class;
    • 생성된 인스턴스에서 Class 클래스를 가져올 수 있습니다.
    String s = new String();
    Class c = s.getClass(); // Object에 정의된 메서드

     

    동적 로딩

    • 컴파일 시 데이터 타입에 바인딩 되는 것이 아닌, 런타임 중에 데이터 타입을 바인딩하는 방법입니다.
    • 프로그래밍 시에는 문자열 변수로 처리했다가 런타임 시에 원하는 클래스를 로딩하여 바인딩 할 수 있습니다.
    • 컴파일 시에 타입이 정해지지 않으므로 동적 로딩시 오류가 발생하면 프로그램의 심각한 장애가 발생할 수 있습니다.

     

    newInstance()

    • new 키워드를 사용하지 않고 클래스 정보를 활용하여 인스턴스를 생성할 수 있습니다.

     

    클래스 정보

    • reflection 프로그래밍 : Class 클래스를 사용하여 클래스의 정보(생성자, 변수, 메서드) 등을 알 수 있고 인스턴스를 생성하고, 메서드를 호출하는 방식의 프로그래밍입니다.
    • 로컬 메모리에 객체가 없는 경우, 원격 프로그래밍, 객체의 타입을 알 수 없는 경우 사용합니다.
    • java.lang.reflect 패키지에 있는 클래스를 활용하여 프로그래밍 합니다.
    • 일반적으로 자료형을 알고 있는 경우엔 사용하지 않습니다.
    Class c = Class.forName("java.lang.String");
    
    Constructor<String>[] constructors = c.getConstructors();
    for(Constructor constructor: constructors){
        System.out.println(constructor); //String 클래스의 생성자 출력
    }
    
    Method[] methods = c.getMethods();
    for(Method method: methods){
        System.out.println(mothod); //String 클래스의 메서드 출력
    }
    Person person = new Person("James");
    System.out.println(person); // James 출력
    
    Class c1 = Class.forName("ch04.Person");
    Person person1 = (Person)c1.newInstance();
    person1.setName("Lee");
    System.out.println(person1); // Lee
    
    Class[] parameterTypes = {String.class}; // 파라미터 타입 배열, 원소는 String 클래스
    Constructor cons = c1.getConstructor(parameterTypes); // Person 클래스의 String을 인자로 받는 생성사
    
    Object[] initargs = {"김유신"}; // 생성자에 들어갈 인자값, (Object type으로 선언)
    Person personLee = (Person)cons.newInstance(initargs); 인자값을 통해 새로운 인스턴스 생성
    System.out.println(personLee); // 김유신

     

     

     

     

    오늘은 모든 클래스의 상위 클래스인 Object 클래스와 여러 메서드에 대해 살펴보았습니다.

    여러 클래스들을 비교할 때 사용하는 값과 오버라이딩을 통해 이를 변화시킬 수 있는 방법을 알게 되어 유용한 개념이었습니다.

    또한, 리플랙션 프로그래밍이라는 새로운 개념에 대해 알게 되어 좋았습니다. newInstance와 같은 경우 deprecated되기도 하여 얼마나 실무적으로 유용한지는 아직 모르겠지만, 같은 메모리 상에 있지 않은 클래스에 대해 핸들링 할 수 있는 방법 중 하나로 알고 있으면 될 것 같다는 생각을 했습니다.

    이 번 시간까지 클래스의 개념에 대해 알아보았습니다. 다음 포스팅에서는 자바에서 사용되는 자료구조 클래스들에 대해 알아보도록 하겠습니다.

    반응형
    LIST

    댓글

Designed by Tistory.