code: public static String fromUtf8(byte[] info, int ofs, int max) {
          StringBuilder result;
          int i;
          int c;
  
          result = new StringBuilder(max - ofs);
          i = ofs;
          while (i < max) {
              c = info[i];
              if (c >= 0) /* same as (c&0x80) == 0, but more efficient */ {
                  i += 1;
              } else {
                  switch (c & 0xe0) {
                  case 0xc0:
                      // 2 bytes for 0x0000 or 0x0080 .. 0x07ff
                      c = ((c & 0x1f) << 6) | (info[i + 1] & 0x3f);
                      i += 2;
                      break;
                  case 0xe0:
                      // 3 bytes for 0x0800 .. 0xffff
                      c = ((c & 0x1f) << 12) | ((info[i + 1] & 0x3f) <<  6) | ((info[i + 2] & 0x3f));
                      i += 3;
                      break;
                  default:
                      throw new RuntimeException("illegal utf8 byte: " + c);
                  }
              }
              result.append((char) c);
          }
          return result.toString();
      }
docs: -- utf encode/decode