본문 바로가기
ComputerScience/Languages

[프로그래밍언어] 자바(2) 언어적 부분

by Develaniper 2021. 6. 21.

1. equals vs ==

자바에서 대표적인 차이의 개념으로 어떤것을 비교하는지에 대한 내용이다.

 

1) equals

  • 객체 자체를 비교하는 방법으로 각 클래스에 Overriding되어 있는 메서드이다.
  • 기본은 ==로 되어있어 비교하며 String의 경우 문자열을 비교하여 같은 문자열인지 확인한다.
  • 즉, 같은 문자열일 경우 true를 다른 문자열일 경우 false를 반환한다.
  public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String aString = (String)anObject;
            if (!COMPACT_STRINGS || this.coder == aString.coder) {
                return StringLatin1.equals(value, aString.value);
            }
        }
        return false;
    }

2) ==

  • 각 값의 주소를 비교하는 연산이다.
  • 단순히 String a = "abc"; 형식의 String을 String b="abc"; 와 ==연산 했을 때  true가 나오는데 이는 heap내에 String Constant pool이라는 영역의 같은 공간을 가리키고 있기 때문이다.
  • String a= new String("abc")와 String b = "abc";와 ==연산을 했을 때는 a는 heap내에 생성된 주소를 가르키고 b는 String constans pool에있는 주솔즐 가리키고 있기 때문에 주소가 달라지므로 false를 반환한다.

2. equals, hashCode

  •  equals 메서드를 오버라이딩 하면 hashCode도 함께 오버라이딩 해야한다.
  • hashCode란 기본적으로 JVM이 부여한 코드값으로 인스턴스가 저장된 가상머신의 주소를 10진수로 반환한 값이다. 
  • A a = new A();와 A a2 = new A()가 있을 경우 기본적으로 a.equals(a2) == false, (a.hashCode==a2.hashCode)==false 이다. (둘다 객체가 새로 생성되고 저장된 주소를 비교하기 때문)
  • 하지만 a와 a1의 내용이 완전 같다면 equals를 오버라이딩 하여 내용이 완전히 동일하다면 true를 리턴해 줄 수 있다.
  • 하지만 이런 경우에도 hashCode값은 다르기 때문에 hashCode 또한 A클래스의 멤버 변수들을 이용하여 동일 변수는 동일 한 hashCode값을 가지게 오버라이딩 해줘야 한다.
  • 예를 들어 HashMap에서 key로 해당 클래스가 쓰일 경우 해시코드 값을 가지고 값을 비교하기 때문에 hashCode를 오버라이딩 하지 않았을 경우에는 내용이 완전 같은 객체더라도 다른 키라고 판단된다.

3. 접근 제어자

private < default < protected < public 순으로 접근을 많이 허용한다.

  • private
    • private가 붙은 변수, 메서드는 해당 클래스에서만 접근이 가능하다.
    • 자바에서는 기본적으로 변수는 private처리하고 메서드를 통해 클래스를 사용하는게 국룰이다. 일반적이다.
  • default
    • 같은 패키지 내에서만 접가능 한 접근제어자로 접근제어자를 따로 설정하지 않은 경우이다.
  • protected
    • 해당 클래스를 포함한 동일 패키지, 해당클래스를 상속받은 클래스에서 접근 가능한 접근제어자이다.
  • public
    • 어떤 클래스에서도 접근이 가능한 접근 제어자이다.

 

4. 클래스 vs 객체 vs 인스턴스

일반적으로 클래스를 붕어빵 틀, 객체를 붕어빵에 비유하곤 한다. 하지만 인스턴스가 곧 객체인지는 생각해 볼 일이다.

 

1) 클래스(Class)

  •  객체를 만들기 위한 설계도 혹은 틀이다.
  • 연관된 변수와 메서드의 집합이다.

2) 객체(Object)

  • 소프트웨어에서 구현할 대상이다.
  • 클래스에 선언된 모양 그대로 생성된 실체라고 할 수 있다.

3) 인스턴스(Instance)

  • 소프트웨어 세계에 구현된 실체
  • 객체를 소프트웨어 세계에 실체화 하면 인스턴스라고 부른다.
  • 즉, 클래스라는 설계도를 바탕으로 메모리를 할당받은 객체라고 할 수 있다.

4) 객체 vs 인스턴스

할당받은 객체를 인스턴스라고 하는것이 맞지만 객체라고 부르는 것이 틀린 건 아니다. 개념적으로 인스턴스는 객체에 포함된다고 할 수 있기 때문이다. 

 다시한번 말하지만 객체는 Object 즉, 실제 세계의 대상을 말하는 것이고, 인스턴스는 메모리를 할당받아 직접 사용하는 소프트웨어 상에서의 객체를 말하는 것이다. 

 

5. 해시 테이블 VS 해시맵

  • 해시테이블과 해시맵은 동일하게 key-value 쌍을 저장하는 자료구조로 key에 해시 함수를 적용한 해시값에 따라 value와 함께 저장하는 것을 말한다.
  • 해시를 사용하면 O(1)만에 데이터에 접근할 수 있는 장점이 있지만 다른 데이터에 대해서 같은 해시값이 나올 수 있어서 이에 따라 해시값이 겹치는 경우 linked List형태로 관리하거나 주변 테이블에 저장을 하는 방법으로 처리할 수 있다. 혹은 resizing을 통해 해시의 범위를 넓히는 방법도 있다.
  • 해시 맵과 해시테이블의 차이점은 동기화인데, 해시테이블은 동기화를 지원하여 Thread-safe하지만 해시 테이블은 Thread-safe하지 않다. 또한 해시 테이블은 key값으로 null값을 지원하지 않는 반면 해시맵은 null값을 지원한다.
  • 즉, 해시맵은 병렬처리를 하지 않을 때 해시테이블은 병렬처리(멀티쓰레드)를 할 때 사용된다.
  • 속도는 해시맵이 더 빠르지만 동기화가 필요할 경우에는 ConcurrentHashMap을 사용하여 보완할 수 있다.

 

6. SOLID

solid는 아무리 생각해도 그냥 말장난 같다.. 말 되는거 가져다 붙여놔서 그럴듯 하게 만든...

  1. Single Responsibility Principle
    • 작성된 클래스는 하나의 기능만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임을 수행하는데 집중되어야한다는 원칙이다.
    • 이에 따라 다른 책임의 변경의 연쇄작용에서 자유로워 질 수 있다는 장점이 있다.
  2. Open Close Principle
    • 확장에는 열려있고, 변경에는 닫혀있어야 한다는 원리이다.
    • 변경을 위한 비용은 가능한 줄이고 확장을 위한 비용은 극대화 해야한다는 의미로 기존 구성요소는 수정이 일어나지 말아야 하며, 기존 구성요소를 쉽게 확장해서 재사용할 수 있어야 한는 뜻이다.
  3. Liskov Subtitution Principle
    • 서브타입은 언제나 기반타입으로 교체될 수 있어야 한다는 뜻이다.
    • 즉 부모 클래스, 인터페이스가 상속받은 자식 클래스와 호환 될 수 있어야 한다는 뜻
    • 다형성과 확장성을 극대화 하려면 하위클래스보다 상위클래스(인터페이스)를 사용하는 것이 좋다.
  4. Interface Segregation Principle 인터페이스 분리 원칙
    • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원리이다. 
    • 즉, 가능한 최소한의 인터페이스만을 사용해야 한다는 것이다.
    • 만일 어떤 클래스를 사용하는 클라이언트가 여러개이고 해당 클래스의 특정 부분만 이용한다면, 이들을 따로 인터페이스로 빼내 클라이언트가 기대하는 메시지만 전달할 수 있도록 하는 것이다.
    • SRP와 ISP는 변화의 적응성을 획득하기 위한 공통적인 목표를 가지고 있는데 SRP는 클래스의 분리, ISP는 인터페이스 분리를 통해 목표에 도달한다.
  5. Dependency Iversion Principle
    • 의존관계의 역전은 하위레벨 모듈의 변경이 상위 레벨 모듈의 변경을 요구하는 관계를 끊는 의미의 역전이다.
    • 의존관계를 맺을 때 변화하기 쉬운것 보단, 변화하기 어려운 것에 의존해야 한다는 것을 의미한다.
    • 변화하기 쉬운 것은 구체적인것, 변화하기 어려운 것은 추상적인 것을 말한다.
    • 구체적인 클래스 보다 인터페이스나 추상클래스와 관계를 맺는 것을 말한다.

7. Wrapper클래스 vs기본형

자바에는 기본형(byte, char, short, int, long, float, double, boolean)와 이를 클래스로 만들어 주는 Wrapper클래스가 있다.

  • Wrapper클래스가 필요한 이유는 Collection이나 Map같은 경우 Generic을 쓰기 때문에 기본형이 아니라 클래스 즉, 객체가 필요하다. 이를 지원해주는 것이 Wrapper클래스이다.
  • 반대로 int, double과 같은 기본형은 왜 존재할까? 모든 변수를 Wrapper로 치환하여 객체로 다루면 더 편하지 않을까? 이는 속도에서 이점을 가져갈 수 있기 때문이다. Wrapper를 사용하면 간단히만 생각해도 변수가 해당 객체의 주소를 가르키기 때문에 2번의 참조가 필요하다(1. 주소참조, 2. 값 참조). 때문에 기본형 타입을 사용하여 더 빠른 연산을 할 수 있다.

 

 

 

 

https://atoz-develop.tistory.com/entry/자바-Object-클래스-정리-toString-equals-hashCode-clone
https://wikidocs.net/232
https://www.nextree.co.kr/p6960/
https://dev-momo.tistory.com/entry/SOLID-원칙

 

댓글