davidB'log

Scala, sugar in Java : no longer stupid accessor

2010-09-12 | lang/java sugar lang/scala

Below I provide the same class in Java and in Scala. The scala class is longer because there @BeanProperty annotation to generate getter and setter (useless in scala). You could also use the @BeanInfo annotation to generate BeanInfo (see Defining a BeanProperty ).

(full source on github )

// Scala
import scala.reflect.{BeanProperty, BeanInfo}

// use @BeanProperty only if you need to integrate with a java framework that require getter/setter (getXxxx/setXxxx)
case class MyScalaStructA(@BeanProperty name : String, @BeanProperty var age : Int)
// Java

class MyJavaStructA {
  private final String _name;
  private int _age;

  // code below generated by IDE (several clicks)
  // need to edit code below if we'll add/remove field

  public MyJavaStructA(String name, int age) {
    this._name = name;
    this._age = age;
  }

  public int getAge() {
    return _age;
  }

  public void setAge(int age) {
    this._age = age;
  }

  public String getName() {
    return _name;
  }

  @Override
  public String toString() {
    return "MyJavaStructA [_name=" + _name + ", _age=" + _age + "]";
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + _age;
    result = prime * result + ((_name == null) ? 0 : _name.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    MyJavaStructA other = (MyJavaStructA) obj;
    if (_age != other._age)
      return false;
    if (_name == null) {
      if (other._name != null)
        return false;
    } else if (!_name.equals(other._name))
      return false;
    return true;
  }

}

I also provide a test case for the scala structure to show the usage.

@Test
def testMyScalaStructA() {
  val a = MyScalaStructA(("A" + 'b').toUpperCase, 30)

  assertEquals("AB", a.name)
  assertTrue("AB" == a.name) //in scala == call equals method
  assertFalse(a.name eq "AB")
  assertEquals("AB", a.getName())
  // a.name = "foo" // read-only => doesn't compile
  //a.setName("foo") // read-only => doesn't compile

  assertEquals(30, a.age)
  a.age = a.age + 1
  assertEquals(31, a.age)
  a.setAge(a.getAge + 1)
  assertEquals(32, a.age)

  // readable default toString generated
  assertEquals("MyScalaStructA(AB,32)", a.toString)

  // equals on field generated
  assertEquals(MyScalaStructA("AB",32), a)
  assertTrue(MyScalaStructA("AB",32) == a)
  assertEquals(MyScalaStructA("AB",32).hashCode, a.hashCode)
}