Groovy 탐색의 메타클래스 함정 기어오르기
이 문제를 분명히 말하기 위해서 먼저 몇 줄의 테스트 코드를 보았다
void testMetaClass() {
def domain = new Domain()
domain.metaClass.p = 'v1'
assertEquals 'v1', domain.p
domain.p = 'v2'
assertEquals 'v2', domain.p
domain.metaClass.p = 'v3'
assertEquals 'v2', domain.p
}
이것은 이미 통과된 테스트이다.
-------------------------------------------------------
Running 1 unit test...
Running test com.grs.GroovyMetaClassTests...null
Empty test suite.
PASSED
Tests Completed in 359ms ...
-------------------------------------------------------
Groovy 테스트 코드의 마지막 두 줄을 확인합니다.
domain.metaClass.p = 'v3'
assertEquals 'v2', domain.p
언뜻 보기엔 답답하다: 집행
domain.metaClass.p = 'v3'
그 다음에 왜domain.p의 값은 여전히'v2'입니까?이것이 바로 내가 함정이라고 부르는 곳이다.보아하니 Groovy에는 이런 규칙이 있는 것 같다. Groovy Object에서 처음으로 통과한 것이다
domain.metaClass.aProperty = aValue
의 방식으로domain에 aProperty를 주입한 후 다시 실행합니다
domain.metaClass.aProperty = yetAnotherValue
domain을 변경할 수 없습니다.aProperty,
domain.aProperty = yetAnotherValue
성공적으로 변경할 수 있습니다.
이 함정에서 벗어나서 우리는 이 문제를 어떻게 해결해야 하는지를 보았다. 나는 어떻게 aProperty가 이미 주입되었는지 알 수 있습니까?다시 말하면, 내가 마땅히 써야 한다는 것을 어떻게 알았겠는가
domain.metaClass.aProperty = yetAnotherValue
그래도
domain.aProperty = yetAnotherValue
네?
나는 두 개의 워크맨이 있다.
1. try를 통해...catch...검사하다
class GroovyFieldAccessor {
static void set(String fieldName, Object obj, Object v) {
def metaPropAlreadyInjected = true
try {
if(obj."$fieldName") {} // do nothing but check if d."$fieldName" will throw an exception.
} catch(x) {metaPropAlreadyInjected = false}
if(metaPropAlreadyInjected) {
obj."$fieldName" = v
} else {
obj.metaClass."$fieldName" = v
}
}
}
2. 매번 두 마디씩 함께 쓴다.
obj.metaClass."$fieldName" = v
obj."$fieldName" = v
만전을 기하다.
개인은 후자를 비교적 좋아한다. 왜냐하면 그것은 두 줄로 매우 간결하기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
java의 Struts2 파일 업로드 및 다운로드 예파일 업로드 Struts 응용 프로그램에서 File Upload 차단기와 Jakarta Commons File Upload 구성 요소로 파일을 업로드할 수 있습니다. Jsp 페이지의 파일 업로드 폼에 파일 탭을 사용...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.