Can't the item.text be assigned to a String in a Android Studio sample code?

The following sample code from https://developer.android.com/guide/topics/text/copy-paste

It seems that there are some errors with the sample code, I have to replace pasteData = item.text with pasteData = item.text.tostring().

Is the sample code wrong?

Sample Code

var clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
var pasteData: String = ""

val item = clipboard.primaryClip.getItemAt(0)

// Gets the clipboard as text.
pasteData = item.text  // It's Wrong, I have to use pasteData = item.text.tostring()

Source Code

enter image description here

2 answers

  • answered 2018-11-08 07:34 Louis Solo

    It might be wrong in real world because we can have a lot of types from clipboard. But in this sample, they already note (at number 3): "The following snip tests this, but it only show code for handling plain text".

  • answered 2018-11-08 09:48 Zoe

    If you take a look at the code, you'll notice that .text returns a CharSequence. Here's the issue:

    • String inherits from CharSequence
    • The method returns a CharSequence
      • But not necessarily a String

    As in, text can return any CharSequence, not necessarily a String. As a result, this isn't a good idea:

    pasteData = item.text as String
    

    Because it will throw a ClassCastException if the CharSequence isn't a String.

    This is where .toString() comes in. It converts the CharSequence to an actual String. In addition, there are two other options:

    1. String.valueOf: pasteData = String.valueOf(item.text)
    2. StringBuilder: pasteData = StringBuilder().append(item.text).toString().

    The reasoning behind this lies in inheritance. Consider this:

    fun someFunction (arg: Int) : CharSequence {
        if(arg < 0) return "This is a String";
        return SomeCustomCharSequenceImpl("Inheritance", 42);
    }
    

    Now, if you invoke this:

    val string: String = someFunction(Random().nextInt()); // The random init is not memory efficient, but it's just for a complete demo
    

    It will not compile, because a CharSequence isn't necessarily a String. The method works because a String is a CharSequence. If you want it as a String, you can convert it to one using one of the three options above.

    Alternatively, if you want to cast it, you could always use is, but that means any other implementations of CharSequence will not do what you expect it to; you wouldn't get the String you need.


    I'm honestly not sure why it uses .text directly in the documentation. Might be a bug, or the API might have changed from String to CharSequence. Either way, you need to convert it.

    TL;DR: Yes, the docs are wrong.