The documentation provides an explanation for this. Play breaks a number of Java conventions with the idea of making the code more readable.
Basically, if you're just going to write:
class A {
private int x;
public int getX() { return x; }
public void setX(int x) { this.x = x; }
}
why not have the framework generate the getters and setters for you (similar to C#)? Of course, since as noted in the documentation, the generated getters and setters are only available at runtime, the fields need to be declared public so the Java compiler won't raise an error if code outside the class accesses the variable.
Basically, this allows you to write:
class A {
public int x;
}
class B {
public void process() {
A a = new A();
a.x = 42;
}
}
instead of:
class B {
public void process() {
A a = new A();
a.setX(42);
}
}
Better yet, if you need specific logic in the getter or setter you can add it in, e.g.:
class A {
public int x;
public void setX(int x) {
if (x < 0) throw new IllegalArgumentException("x must be positive");
this.x = x;
}
}
and still use this like so:
class B {
public void process() {
A a = new A();
a.x = 42;
}
}
Whether or not this is the right way to handle things is, of course, a matter of opinion, but it's pretty common for Java developers to look for easier ways of writing all those boilerplate getters and setters (whatever it's relative merits, Groovy, Jython, JRuby, and Fantom all provide a mechanism for creating and accessing properties that results in syntax similar to what Play is achieving; Rhino at least provides a similar syntax for calling accessors and even Scala has a simpler mechanism to add accessors).