equals 메소드와 관련된 Java 코드
시험 연습을했는데 이해가 안되는 샘플 문제를 발견했습니다.
다음 코드의 경우 출력 내용을 찾습니다.
public class Test {
private static int count = 0;
public boolean equals(Test testje) {
System.out.println("count = " + count);
return false;
}
public static void main(String [] args) {
Object t1 = new Test();
Object t2 = new Test();
Test t3 = new Test();
Object o1 = new Object();
++count; t1.equals(t2);
++count; t1.equals(t3);
++count; t3.equals(o1);
++count; t3.equals(t3);
++count; t3.equals(t2);
}
}
이 코드의 출력은 count = 4
이지만 이유를 이해할 수 없습니다. 누구든지 나를 도울 수 있습니까?
가장 먼저 주목해야 할 것은 인수가 대신 이므로 서명이 일치하지 않기 때문에 's를 재정의 public boolean equals(Test testje)
하지 않는다는 것입니다 .Object
equals
Test
Object
따라서 main
메서드는 equals(Test testje)
실행시 정확히 한 번만 호출 t3.equals(t3);
합니다. 인스턴스의 정적 유형 equals
과 인수 유형이 모두 Test
클래스 인 유일한 경우이기 때문입니다 .
t3.equals(t3);
네 번째 equals
문 (정적 count
변수 의 4 개 증분 뒤에 오는 )이므로 4가 인쇄됩니다.
다른 모든 equals
문은 Object
's를 실행 equals
하므로 아무것도 인쇄하지 않습니다.
더 자세한 설명 :
t1.equals()
통화 Object
의 equals
의 정적 (컴파일 시간) 유형이 있기 때문에, 관계없이 인수의 유형 t1
입니다 Object
, 그리고 Test
클래스는이 메소드를 오버라이드 (override)하지 않습니다. Object
클래스는없는 equals
하나의 방법으로 Test
인자이므로 equals(Test testje)
상관없이 동적 (런타임 타입) 중이라고 할 수 없다 t1
.
t3.equals()
어느 실행할 수 Object
의 equals
또는 Test
의 컴파일 시간 형 이후의 같음은 t3
인 Test
및 Test
클래스는 두 갖는 equals
방법 (로부터 상속 된 Object
클래스와 다른 정의 Test
클래스).
선택되는 방법은 인수의 컴파일 시간 유형에 따라 다릅니다. 1. 인수가 Object
( t3.equals(o1);
또는 에서 와 같이 t3.equals(t2);
) 인 경우 Object
's equals
가 호출되고 아무것도 인쇄되지 않습니다. 2. Test
에서와 같이 인수가이면 t3.equals(t3);
두 버전 모두 equals
해당 인수와 일치하지만 메서드 오버로딩 규칙으로 인해 가장 구체적인 인수 equals(Test testje)
--가 있는 메서드 가 선택되고 count
변수가 인쇄됩니다.
Test의 equals 메소드는 Test의 인스턴스를 사용합니다.
이전의 모든 시도는 Object 클래스에서 상속 된 메서드를 사용하는 Object 인스턴스로 수행되었습니다.
public boolean equals(Object o){
return this == o;
}
거기에 인쇄물이 없기 때문에 어떤 값도 인쇄하지 않습니다.
당신 ++count;
은 카운트 값을 증가시킬 것이므로 실제로 전화를 거는 순간
public boolean equals(Test testje){...
그 값을 인쇄하는 방법, count의 값은 4입니다.
t3.equals(t3)
메서드 시그니처와 일치하는 올바른 인수를 가진 유일한 줄 public boolean equals (Test testje)
이므로 실제로 해당 print 문을 호출하는 프로그램의 유일한 줄입니다. 이 질문은 몇 가지를 가르치기 위해 고안되었습니다.
- 모든 클래스는 암시 적으로 Object를 확장합니다.
- Object.java에는 Object 유형을 취하는 equals 메소드가 있습니다.
- 인수가 다른 경우 동일한 이름의 여러 메서드가 존재할 수 있습니다.이를 메서드 오버로딩이라고합니다.
- 누구의 서명이 런타임에 인수와 일치하는지 메서드 메서드 오버로드가 호출되는 메서드입니다.
본질적으로 여기서 트릭은 Test가 모든 자바 클래스처럼 암시 적으로 Object를 확장한다는 것입니다. Object에는 Object 유형을 취하는 equals 메소드가 있습니다. t1 및 t2는 런타임에 인수가 Test에 정의 된 equals의 메서드 시그니처와 일치하지 않도록 형식화됩니다. 대신 기본 유형이 Object 인 경우 액세스 권한이있는 유일한 메소드가 Object.java에 정의 된 메소드이거나 파생 된 유형이 Object이기 때문에 항상 Object.java의 equals 메소드를 호출합니다.
public boolean equals(Test testje)
Cannot be entered because in that case at runtime the argument is of type Object which is a Superclass of Test, not a subclass. So instead it looks at the equals method in the Test.java's implicitly typed superclass Object.java which also contains an equals method, which just happens to have a method signature of
public boolean equals (Object o)
which in this case match our arguments at runtime so this equals method is the one that executes.
Notice in the case of t3.equals(t3)
both the base type and the derived type of t3 are Test.
Test t3 = new Test ();
this means that at runtime you are calling the equals method in Test.java and the argument you are passing in is actually of type Test so the method signatures match and the code inside Test.java executes. At this point count == 4
.
Bonus bit of knowledge for you:
@Override
annotation you may have seen in a few places explicitly instructs the compiler to fail if it does not find method with the exact same signature somewhere in a Superclass. This is useful to know if you definitely intend to override a method and you want to be absolutely sure that you really are overriding the method and you haven't accidentally changed the method in either the superclass or subclass but not both and Introduced a runtime error where the wrong implementation of the method is being called causing unwanted behavior.
There's two key things that you should know.
Overridden methods must have the exact signatures as their superclass have. (in your example this condition doesn't meet.)
In Java for an object, we have two types: compile type and runtime type. In the following example compile type of
myobj
isObject
but its runtime type isCar
.public class Car{ @Override public boolean equals(Object o){ System.out.println("something"); return false; } }
Object myobj = new Car();
Also you should note that
myobj.equals(...)
results in printingsomething
in the console.
참고URL : https://stackoverflow.com/questions/34813675/java-code-related-to-equals-method
'Program Tip' 카테고리의 다른 글
PyCharm 내에서 (Ana) conda 사용 (0) | 2020.10.21 |
---|---|
RuntimeError : 모듈이 API 버전 A에 대해 컴파일되었지만이 버전의 numpy는 9입니다. (0) | 2020.10.21 |
R에 "붙여 넣기"로 변수 이름을 만드시겠습니까? (0) | 2020.10.21 |
Nginx를 사용한 WSGI 대 uWSGi (0) | 2020.10.21 |
Rails .where 대 .find (0) | 2020.10.21 |