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!!!!