모든 객체가 상속받는 Object클래스에 정의되어 있지만 단순히 == 연산자로 참조값이 같은지를 비교한다.
그렇기 때문에 동일한 값을 같더라도 true가 나오지 않고 false가 나온다.
Object클래스의 equals를 오바라이딩해서 값이 같으면 객체가 같다라고 판단하게 만들 수 있다.
String 클래스가 대표적인 예이다.
// String classpublicbooleanequals(ObjectanObject){if(this==anObject){// 기본적인 참조값 비교returntrue;}if(anObjectinstanceofString){// String 값을 하나하나 받아서 비교StringanotherString=(String)anObject;intn=value.length;if(n==anotherString.value.length){charv1[]=value;charv2[]=anotherString.value;inti=0;while(n--!=0){if(v1[i]!=v2[i])returnfalse;i++;}returntrue;}}returnfalse;}
toString
String toString()
문자열 타입으로 변경시켜주는 메소드
toString을 오버라이딩하면 객체를 print할 시, toString이 호출 된다.
Aa=newA();// System.out.println(a);// 객체의 메모리 주소가 나x온다// A 클래스 안에 toString을 오버라이딩 한 후@OverridepublicStringtoString(){return"People [name="+name+", age="+age+"]";}System.out.println(a2);// People [name= "내가 넣은이름", age= "내가 넣은 나이"] 가나온다.
hashcode
int hashCode()
객체를 식별할 하나의 정수값을 말한다.
equals()가 true인 두 Object를 HashMap에 put을 할 때 동일한 key로 인식하고 싶은 경우에 사용한다.
HashSet, HashMap, HashTable 등등.. 에서 HashCode()의 리턴값이 true 이고 equals()의 리턴값이 true이면 동일한 객체로 본다.
다만 hash 코드값이 같다고 해서 객체의 참조 값이 같은 것은 아니다.
// int형 num 멤버 필드를 가지고 있고 equals()가 오버라이딩된 A라는 클래스가 있고 가정한다.Ac1=newA(10);Ac2=newA(10);// 멤버 필드가 같은 객체를 생성한다.System.out.println(c1.equals(c2))// trueMap<A,Integer>map=newHashMap<A,Integer>();map.put(c1,1);map.put(c2,1);System.out.println(map.size());// hashCode를 오버라이딩 했으면 같은 객체로 판단하므로 1, 아니면 2가 나온다.// hashCode 오버라이딩 부분 (num 값이 같으면 hashCode가 같아진다.)// hashCode 연산 할 때는 소수를 사용한다. (이점은 분명하지 않지만.. 그렇게 사용되어왔다.)publicinthashCode(){finalintprime=31;inthashCode=1;hashCode=prime*hashCode+num;returnhashCode;}
getClass
Class getClass()
객체의 package명 + 클래스이름을 가져오는 클래스 타입의 메소드
toString으로 객체를 표현할 때 사용할 수 있다.
// 위에 A클래스의 toString을 오버라이딩 한다고 가정한다. (A클래스는 edu라는 패키지에 속해있다고 가정한다.)publicStringtoString(){Classc=getClass();return"<"+c.getName()+": num ="+num+">";}// main 부분Aa=newA(12);System.out.println(a);// <edu.A : num = 12> 라는 결과가 나온다.// getName()을 사용하지 않고 getSimpleName() 을 사용할 시 edu.A가 아닌 A라고만 나온다.
클래스에서 속성을 뽑아 낼 때 사용할 수 있다.
일반적인 프로그래밍에서 수행하진 않지만 프레임워크에서 자주 수행된다고 한다. (정확하진 않음)
Aa=newA(12);Classc=a.getClass();for(Fieldf:c.getDeclaredFields()){// getDeclaredFields : 해당 클래스에서 정의된 변수 목록을 field 클래스 배열 타입으로 리턴한다.f.setAccessible(true);// setAccessible : private 접근제어 선언이 되어 있는 경우, 접근을 가능하게 해준다.try{System.out.println(f.getName()+" = "+f.get(a));}catch(Exceptione){e.printStackTrace();}}// num = 12 라는 결과가 나온다. (물론, 필드가 더 있다면 다른 필드도 나올 것이다.)// 이런식으로 필드를 뽑아내면 캡슐화의 의미가 있을까? 라는 의문이 들었지만 try catch로 예외처리를 해주면 된다.
“IllegalAccessException : cannot access class …” 에러 해결 방법(Intellij)
다양한 라이브러리를 사용하다 보면 IllegalAccessException : cannot access class ... 에러를 마주칠 때가 있습니다.
...
댓글남기기