3

I've just spent hours debugging some code because I forgot (actually never considered it) that TextView.getText() returns CharSequence that may be in fact a mutable class...

Shouldn't it return (immutable) String instead? I mean I can't imagine a situation when you want to share a state with a text field, at least not by default.

Isn't that something that can be objectively called a design mistake in a library?

gnat
  • 21,442
  • 29
  • 112
  • 288
zduny
  • 2,623
  • 2
  • 19
  • 24
  • what do method javadocs say? I ask because it often happens that tricky design decisions like that are explained in javadocs. Wild guess - this could be done to address mobile device resource limitations: passing back and forth and mutating `StringBuilder`s could be "cheaper" than messing with / optimizing multiple instances of immutable `String`s – gnat May 07 '14 at 21:44
  • @gnat See for yourself: http://developer.android.com/reference/android/widget/TextView.html#getText() . Yeah, performance is the obvious reason, still I believe documentation could use some warning... – zduny May 07 '14 at 21:49
  • I see. Yet another reason there: "you can cast the return value from this method to Spannable or Editable" - String wouldn't allow for that. And this makes me feel it's supposed to support frequent changes, yet another point to prefer something mutable (in _mobile_ context), like StringBuilder: "TextView is a complete text editor..." – gnat May 07 '14 at 21:55

1 Answers1

2

Well, most immediate justification for this design decision can be found in method javadocs:

you can cast the return value from this method to Spannable or Editable...

Casts mentioned above are possible only because Spannable and Editable implement CharSequence; String wouldn't allow for that.

For a deeper understanding of the design motivation, take a look at class javadocs:

TextView is a complete text editor...

Above means that TextView object is designed to support frequent changes of its content.

If getText would return immutable String, this would mean a high chance of creating multiple objects while working with TextView. This in turn would go against general approach preferred in Android and outlined in Avoid Creating Unnecessary Objects guidelines:

Object creation is never free. A generational garbage collector with per-thread allocation pools for temporary objects can make allocation cheaper, but allocating memory is always more expensive than not allocating memory.

As you allocate more objects in your app, you will force a periodic garbage collection, creating little "hiccups" in the user experience. The concurrent garbage collector introduced in Android 2.3 helps, but unnecessary work should always be avoided.

Thus, you should avoid creating object instances you don't need to...

For the sake of completeness, it is worth noting that reasoning in above guidance implicitly involves mobile applications specifics.

In particular, one can imagine desktop or server platforms having more sophisticated garbage collection, allowing developers to design immutable objects at their discretion, without worrying much about performance implications.

At mobile platforms, API designers have to take into account resource limitations of mobile devices (memory, processor, power consumption etc) that can block implementation of theoretically better approaches.

gnat
  • 21,442
  • 29
  • 112
  • 288