Search code examples
groovyhashmapextend

Groovy extended hashmap with a field


This doesn't work. Shouldn't it?

class WeirdBean extends HashMap {
  public String inner = "set within"
  def getInner() { return this.inner }
  def getOuter() { return this.outer }
}

def o = WeirdBean.newInstance()
o.outer = "set without"
println o.getOuter()  // set without
println o.outer       // set without
assert o.outer == o.getOuter() // Pass

println o.getInner()  // set within
println o.inner       // null, even though public
assert o.inner == o.getInner() // Fail, o.inner is null

Solution

  • Seems like Map::get has higher precedence than object.field or object.property. Since a field access inside a class doesn't go through the getter, this works:

    class WeirdBean extends HashMap {
      public String inner = "set within"
      def getInner() { return this.inner }
    
      def getProperty(String property) { 
        (property == 'inner') ? inner : super.get(property) 
      }
    
      def getOuter() { return this.outer }
    }
    
    def o = WeirdBean.newInstance()
    o.outer = "set without"
    println o.getOuter()  // set without
    println o.outer       // set without
    assert o.outer == o.getOuter() // Pass
    
    println o.getInner()  // set within
    println o.inner       // null, even though public
    assert o.inner == o.getInner() // Fail, o.inner is null