code: public static byte[] toUtf8(String str) {
          int i, max;
          char c;
          int len;
          byte[] result;
  
          max = str.length();
          len = 0;
          for (i = 0; i < max; i++) {
              c = str.charAt(i);
              if ((c >= 0x0001) && (c <= 0x007f)) {
                  len += 1;
              } else {
                  if ((c == 0) || ((c >= 0x0080) && (c <= 0x07ff))) {
                      len += 2;
                  } else {
                      len += 3;
                  }
              }
          }
          if (len > 0xffff) {
              throw new IllegalArgumentException("string too long: " + str.length() + "/" + len);
          }
          result = new byte[1 + 2 + len];
          result[0] = CONSTANT_UTF8;
          result[1] = (byte) (len >> 8);
          result[2] = (byte) len;
          len = 3;  // used for current position
          for (i = 0; i < max; i++) {
              c = str.charAt(i);
              if ((c >= 0x0001) && (c <= 0x007f)) {
                  result[len] = (byte) c;
                  len += 1;
              } else {
                  if ((c == 0) || ((c >= 0x0080) && (c <= 0x07ff))) {
                      result[len + 0] = (byte) ((c >> 6) | 0xc0);
                      result[len + 1] = (byte) ((c & 0x3f) | 0x80);
                      len += 2;
                  } else {
                      result[len + 0] = (byte) ((c >> 12) | 0xe0);
                      result[len + 1] = (byte) (((c >> 6) & 0x3f) | 0x80);
                      result[len + 2] = (byte) ((c & 0x3f) | 0x80);
                      len += 3;
                  }
              }
          }
          if (len != result.length) {
              throw new IllegalStateException(len + " vs " + result.length);
          }
          return result;
      }
docs: This implementation differs from String.getBytes("UFT-8"), e.g. when decoding 0.