>

다음 코드가있는 경우 :

class Person {
    String getName() {
        "John Doe"
    }
    boolean isMan() {
        true
    }
}
println new Person().properties

그런 다음 인쇄합니다 :

[class:class Person, man:true, name:John Doe]

그루비가 접근 자 메서드를 기반으로 속성 (사람, 이름)을 생성하지 못하게하려면 어떻게해야합니까? groovy가 속성을 생성하는 이유를 이해하지만 groovy가이를 수행하지 못하게하는 방법 (예 : 주석 사용)이있을 것으로 기대했습니다.


  • 답변 # 1

    new Person().properties 를 알고 있어야합니다  클래스 필드 측면에서 클래스 속성 목록을 반환하지 않고 메타 클래스 속성을 반환합니다. Groovy는 MetaBeanProperty 라는 클래스를 사용합니다.  -클래스 필드와 접근 자 메서드를 모두 나타냅니다. Groovy 클래스를 컴파일하면 .class 를 얻을 수 있습니다  다음과 같이 디 컴파일되는 파일 :

    import groovy.lang.GroovyObject;
    import groovy.lang.MetaClass;
    import org.codehaus.groovy.runtime.callsite.CallSite;
    public class Person implements GroovyObject {
        public Person() {
            CallSite[] var1 = $getCallSiteArray();
            MetaClass var2 = this.$getStaticMetaClass();
            this.metaClass = var2;
        }
        public String getName() {
            CallSite[] var1 = $getCallSiteArray();
            return "John Doe";
        }
        public boolean isMan() {
            CallSite[] var1 = $getCallSiteArray();
            return true;
        }
    }
    
    

    아시다시피 getter 메소드에 대해 작성된 파일이 없습니다. 그러나 new Person().properties   name 를 반환  그리고 man   MetaBeanProperty 로 인해 속성 .

    클래스 필드의 맵만 가져 오려면 new Person().properties 가 반환 한 맵을 필터링해야합니다. . 와이즈 비즈  클래스는이 방법을 MetaBeanProperty  그 getField() 를 반환  주어진 CachedField  클래스 필드와 MetaBeanProperty 로 표시됩니다.  그렇지 않으면. 다음 예를 고려하십시오.

    null
    
    
    이 예에서는 import groovy.transform.CompileStatic import groovy.transform.TypeChecked @CompileStatic @TypeChecked class Person { String email String getName() { "John Doe" } boolean isMan() { true } static void main(String[] args) { def person = new Person() def fields = person.properties.findAll { (person.hasProperty(it.key.toString()) instanceof MetaBeanProperty) && ((MetaBeanProperty) person.hasProperty(it.key.toString())).getField() != null } println fields } } 필드를 추가했습니다 . 위에서 설명한 규칙에 따라 속성 목록을 필터링하면 다음 맵이 반환됩니다.

    email
    
    

    마지막으로-이것이 [email:null] 를 수정 한 것입니다.   Person 를 디 컴파일 한 후 클래스가 보였습니다.  파일 :

    .class
    
    

    다시, import Person._main_closure1; import groovy.lang.GroovyObject; import groovy.lang.MetaClass; import groovy.lang.Reference; import java.util.Map; import org.codehaus.groovy.runtime.DefaultGroovyMethods; public class Person implements GroovyObject { private String email; public Person() { MetaClass var1 = this.$getStaticMetaClass(); this.metaClass = var1; } public String getName() { return "John Doe"; } public boolean isMan() { return true; } public static void main(String... args) { Reference person = new Reference(new Person()); Map fields = DefaultGroovyMethods.findAll(DefaultGroovyMethods.getProperties((Person)person.get()), new _main_closure1(Person.class, Person.class, person)); DefaultGroovyMethods.println(Person.class, fields); Object var10000 = null; } public String getEmail() { return this.email; } public void setEmail(String var1) { this.email = var1; } }  그리고 getName()  메소드는 클래스 필드를 작성하지 않습니다. isMan()  기본 Groovy 범위를 가진 필드는 접근 자 메소드를 사용하여 개인 클래스 필드로 변환됩니다. 도움이 되길 바랍니다.

    클래스 속성은 어디에 생성됩니까?

    email 가있는 장소를 보거나 디버그하려는 경우  지도가 만들어졌습니다. new Person().properties 를보세요.  이것은 클래스 2083의 메소드입니다. 이것은 클래스가 메타 클래스에서 특성 목록을 가져 오기 위해 호출하는 메소드입니다. 보시다시피 캐시 된 필드 (실제 클래스 필드)와 메타 빈 속성 (필드 또는 접근 자 메서드로 표시 될 수있는 속성)의 두 가지 속성 유형을 허용합니다. MetaClassImpl.getProperties() 에서 getter 메소드를 검색하지 못하게하는 옵션이 없습니다.  불행히도 방법.

    getProperties() 에서 접근 자 메소드를 제외하려는 경우  그런 다음 이것을 달성하는 유일한 방법은 메소드의 이름을 바꾸어 접근 자 메소드로 표시되지 않는 것입니다 (예 : new Person().properties  -> getName() ). 이 경우 Groovy의 메타 클래스는 그러한 메소드에 대한 메타 빈 특성을 검색하지 않으며 리턴하는 값은 name() 에 존재하지 않습니다.  지도.

    new Person().properties

  • 이전 vba - 테이블의 셀에 문자가 포함되어 있으면 다른 셀 행이 자동으로 만들어 지도록 루프를 만드는 방법
  • 다음 ibm midrange - 접두사 파일에 대한 SETLL READE