2012-10-17 43 views
29

Tôi muốn sử dụng giá trị của thuộc tính dự kiến ​​hoặc mặc định được chỉ định. Làm thế nào để đạt được điều này trong groovy?Cách xác minh xem một đối tượng có thuộc tính nhất định không?

Hãy nhìn vào ví dụ:

def printName(object) { 
    //if object has initialized property 'name' - print 'name', otherwise print ToString 
    if (object<some code here>name && object.name) { 
     print object.name 
    } else { 
     print object 
    } 
} 

Trả lời

57

Bạn có thể sử dụng hasProperty. Ví dụ:

if (object.hasProperty('name') && object.name) { 
    println object.name 
} else { 
    println object 
} 

Nếu bạn đang sử dụng một biến cho tên thuộc tính, bạn có thể sử dụng này:

String propName = 'name' 
if (object.hasProperty(propName) && object."$propName") { 
    ... 
} 
+0

+1 Tốt hơn tôi ... Tôi không nên bắt đầu từ metaClass ;-) –

+4

'# hasProperty' thực sự trả về [MetaProperty] (http://groovy.codehaus.org/api/groovy/lang/MetaProperty .html), vì vậy bạn cũng có thể làm điều gì đó như 'object.hasProperty (propName) ?. getProperty (đối tượng)?: defval' –

+1

... và có một số mâu thuẫn trong groovyDoc (groovy-2.4.7): _Description_ bắt đầu với '' 'Trả về true của MetaClass thực hiện có một thuộc tính của tên đã cho ' '' _Returns_ là viết tắt của '' 'Tìm thấy MetaProperty hoặc null nếu nó không tồn tại''' là sự thật –

6

Giả sử bạn object là một lớp Groovy, bạn có thể sử dụng hasProperty trong đối tượng metaClass như vậy:

def printName(o) { 
    if(o.metaClass.hasProperty(o, 'name') && o.name) { 
    println "Printing Name : $o.name" 
    } 
    else { 
    println o 
    } 
} 

Vì vậy, sau đó đưa hai lớp:

class Named { 
    String name 
    int age 

    String toString() { "toString Named:$name/$age" } 
} 

class Unnamed { 
    int age 

    String toString() { "toString Unnamed:$age" } 
} 

Bạn có thể tạo cá thể o f họ, và thử nghiệm:

def a = new Named(name: 'tim', age: 21) 
def b = new Unnamed(age: 32) 

printName(a) 
printName(b) 

nào nên đầu ra:

Printing Name : tim 
toString Unnamed:32 
+1

Cảm ơn Tim, tại sao tôi phải truy cập vào bất động sản lớp từ metaclass và không theo cách thông thường (nghĩa là. object.hasProperty ('name'))? –

-2

Nếu tôi chỉ đơn giản là muốn khẳng định rằng một đối tượng có một số tài sản, tôi chỉ kiểm tra sau:

assertNotNull(myObject.hasProperty('myProperty').name) 

Nếu myObject không có myProperty sự khẳng định sẽ thất bại với một con trỏ ngoại lệ null:

java.lang.NullPointerException: Cannot get property 'name' on null object 
1

Bạn có thể viết phương pháp riêng của bạn thông qua meta-lập trình:

class Foo { 
    def name = "Mozart" 
} 

def f = new Foo() 

Object.metaClass.getPropertyOrElse = { prop, defaultVal -> 
    delegate.hasProperty(prop) ? delegate."${prop}" : defaultVal 
} 

assert "Mozart" == f.getPropertyOrElse("name", "") 
assert "Salzburg" == f.getPropertyOrElse("city", "Salzburg") 
Các vấn đề liên quan