code: public static int utf8SizeInBytes(CharSequence string) {
      int sizeInBytes = 0;
      for (int i = 0, len = string.length(); i < len; i++) {
        char ch = string.charAt(i);
        if (ch < 0x80) {
          sizeInBytes++; // 7-bit ASCII character
          // This could be an ASCII run, or possibly entirely ASCII
          while (i < len - 1) {
            ch = string.charAt(i + 1);
            if (ch >= 0x80) break;
            i++;
            sizeInBytes++; // another 7-bit ASCII character
          }
        } else if (ch < 0x800) {
          sizeInBytes += 2; // 11-bit character
        } else if (ch < 0xd800 || ch > 0xdfff) {
          sizeInBytes += 3; // 16-bit character
        } else {
          int low = i + 1 < len ? string.charAt(i + 1) : 0;
          if (ch > 0xdbff || low < 0xdc00 || low > 0xdfff) {
            sizeInBytes++; // A malformed surrogate, which yields '?'.
          } else {
            // A 21-bit character
            sizeInBytes += 4;
            i++;
          }
        }
      }
      return sizeInBytes;
    }
docs: This returns the bytes needed to transcode a UTF-16 Java String to UTF-8 bytes.
  
  <p>Originally based on
  http://stackoverflow.com/questions/8511490/calculating-length-in-utf-8-of-java-string-without-actually-encoding-it
  
  <p>Later, ASCII run and malformed surrogate logic borrowed from okio.Utf8