详解JDK1.6 java.net.URLEncoder包下的超链接编码工具类Encoder

  JDK1.6,在该类下,包含一个静态初始化代码块 和 两个静态编码方法,形如下

 static{}

  public static String encode(String paramString);

  public static String encode(String paramString1, String paramString2)

    throws UnsupportedEncodingException;

静态代码块如下:

 static
  {
    dontNeedEncoding = new BitSet(256);//URLEncoder类的属性,位集,用于设置特定索引是true,还是false;
    for (int i = 97; i <= 122; ++i)//将小写字母对应的索引对应的值设置为true
      dontNeedEncoding.set(i);
    for (i = 65; i <= 90; ++i)
      dontNeedEncoding.set(i);//将大写字母对应的索引对应的值设置为true
    for (i = 48; i <= 57; ++i)
      dontNeedEncoding.set(i);//将数字0-9对应的索引对应的值设置为true
    dontNeedEncoding.set(32);//空格
    dontNeedEncoding.set(45);//-
    dontNeedEncoding.set(95);//_
    dontNeedEncoding.set(46);//.
    dontNeedEncoding.set(42);//*
    dfltEncName = (String)AccessController.doPrivileged(new GetPropertyAction("file.encoding"));//默认情况下读取java系统变量fie.encoding 的编码值
  }

第一个静态编码方法(过时了)

  public static String encode(String paramString)
  {
    String str = null;
    try
    {
      str = encode(paramString, dfltEncName);//此处调用第二个静态编码方法,详见下面
    }
    catch (UnsupportedEncodingException localUnsupportedEncodingException)
    {
    }
    return str;
  }


第二个静态编码方法

public static String encode(String paramString1, String paramString2)//第一个参数为:待编码字符序列;第二个参数:编码方式,如gbk ,gb2312,utf-8等
    throws UnsupportedEncodingException
  {
    Charset localCharset;//用于保存通过反射,获取对应的字符编码集
    int i = 0;//标识,标志,是否
    StringBuffer localStringBuffer = new StringBuffer(paramString1.length());//用于保存转化后的字符序列
    CharArrayWriter localCharArrayWriter = new CharArrayWriter();//本地字符数组输出流,用于转化特殊字符时的过渡容器
    if (paramString2 == null)
      throw new NullPointerException("charsetName");//传入编码为空,抛出异常
    try
    {
      localCharset = Charset.forName(paramString2);//通过反射,获取对应的字符编码集
    }
    catch (IllegalCharsetNameException localIllegalCharsetNameException)
    {
      throw new UnsupportedEncodingException(paramString2);
    }
    catch (UnsupportedCharsetException localUnsupportedCharsetException)
    {
      throw new UnsupportedEncodingException(paramString2);
    }
    int j = 0;
    while (j < paramString1.length())//通过一个遍历,将第一个参数的每一位通过转化,保存进localStringBuffer里边
    {
      int k = paramString1.charAt(j);
      if (dontNeedEncoding.get(k))//如果是初始化块中定义的字符
      {
        if (k == 32)//如果是空格
        {
          k = 43;//将空格符转成+字符
          i = 1;
        }
        localStringBuffer.append((char)k);//将初始化块中定义的字符原样添加到返回变量
        ++j;
      }
      else
      {
        do
        {
          localCharArrayWriter.write(k);//将位集为false的字符放入返回变理
          if ((k >= 55296) && (k <= 56319) && (j + 1 < paramString1.length()))
          {
            int l = paramString1.charAt(j + 1);
            if ((l >= 56320) && (l <= 57343))
            {
              localCharArrayWriter.write(l);//如果是UNICODE编码的话,再添加一个字符
              ++j;
            }
          }
          if (++j >= paramString1.length())//遍历到第一个参数的最后一个字符,跳出循环
            break;
        }
        while (!(dontNeedEncoding.get(k = paramString1.charAt(j))));//过滤掉索引为j,对应的位集值为false的字符
        localCharArrayWriter.flush();//当前索引为J,已经完成了添加字符到localCharArrayWriter容器,刷新缓冲输出容器
        String str = new String(localCharArrayWriter.toCharArray());//重新生成字符串
        byte[] arrayOfByte = str.getBytes(localCharset);//通过特定字符集localCharset,转化成字节数组
        for (int i1 = 0; i1 < arrayOfByte.length; ++i1)
        {
          localStringBuffer.append('%');//针对当前的j对应的字符(前提是该字符不是初始化定义为true的字符),在前面添加%字符
          char c = Character.forDigit(arrayOfByte[i1] >> 4 & 0xF, 16);//将i1的高四位整型转对应的字符(<10  转成‘0’-‘10’,大于10转成'A'-'F')
          if (Character.isLetter(c))
            c = (char)(c - ' ');//如果是字母,转成字母对应的ascci
          localStringBuffer.append(c);
          c = Character.forDigit(arrayOfByte[i1] & 0xF, 16);//将i1的低四位整型转对应的字符(<10  转成‘0’-‘10’,大于10转成'A'-'F')
          if (Character.isLetter(c))//同上
            c = (char)(c - ' ');
          localStringBuffer.append(c);
        }
        localCharArrayWriter.reset();//处理完后,重置容器
        i = 1;
      }
    }
    return ((i != 0) ? localStringBuffer.toString() : paramString1);//如果标记为0,则表示第一个参数里边只包含初始化块里边定义的字符(除32空格外),直接返回第一个参数,否则返回经过处理的字符序列。

  }

附录:Character下的forDigit方法的源代码

  public static char forDigit(int paramInt1, int paramInt2)
  {
    if ((paramInt1 >= paramInt2) || (paramInt1 < 0))
      return ';
    if ((paramInt2 < 2) || (paramInt2 > 36))
      return ';
    if (paramInt1 < 10)
      return (char)(48 + paramInt1);
    return (char)(87 + paramInt1);
  }


OVER!!!!


你可能感兴趣的:(详解JDK1.6 java.net.URLEncoder包下的超链接编码工具类Encoder)