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?

  • 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 StringBuilders could be "cheaper" than messing with / optimizing multiple instances of immutable Strings – gnat May 7 '14 at 21:44
  • @gnat See for yourself: developer.android.com/reference/android/widget/… . Yeah, performance is the obvious reason, still I believe documentation could use some warning... – mrpyo May 7 '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 7 '14 at 21:55

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.