Java基础Demo -- 基本类型转换字节流

基本类型转换为字节流

字节流转换回基本类型

 注意理解:

0xff &0xff java移位仅支持int或long

>>带符号右移(负数高位补1,正数高位补0),相当于除以2的n次方

>>>无符号右移(高位补0)

<<左移(低位补0),相当于乘以2的次方

/**
* ASCII码 0x00~0x7F
* ISO8859-1/Latin-1西欧标码
* gb2312中文简体 16进制范围0xB0A1~0xF7FE unicode表示范围\u4E00~\u9FA5 \uF900~\uFA2D
* GBK扩充的gb2312 16进制范围0x8140~0xFEFE
* 表示汉字的首1位bit都为1,而ASCII首1位bit为0,所以GBK编码时,判断是否汉字if(bytex<0)
* UTF-16LE小头(低位为0) 中文/英文字符都是占据两个字节 也叫Unicode编码 (JVM就是处理Unicode值的) 举例:'a' 0x6100
* UTF-16BE大头(高位为0) 中文/英文字符都是占据两个字节 也叫Unicode编码 (JVM就是处理Unicode值的) 举例:'a' 0x0061
* UTF-8编码  高8位是111打头的表示随后的三个字节凑在一起才是一个字符 例如中文
*                    高8位是110打头的表示随后的两个字节凑在一起才是一个字符 例如脱离ISO8859-1范围的字符
*                    高8位的首位是0的表示单字节的字符 例如ASCII范围内的字符
* UTF-32编码 每个字符都是硬性规定占4个字节
*/

/**
* ASCII码 0x00~0x7F
* ISO8859-1/Latin-1西欧标码
* gb2312中文简体 16进制范围0xB0A1~0xF7FE(其中有5个空位是D7FA-D7FE) unicode表示范围\u4E00~\u9FA5 \uF900~\uFA2D
* GBK扩充的gb2312 16进制范围0x8140~0xFEFE
* 由于表示汉字或图形符号的“高位字节”的首个bit都为1,而ASCII首个bit为0,而实现了这两种字符集对ASCII的兼容
* UTF-16LE小头(低位为0) 中文/英文字符都是占据两个字节 也叫Unicode编码 (Java内部机制就是处理Unicode值的) 举例:'a' 0x6100
* UTF-16BE大头(高位为0) 中文/英文字符都是占据两个字节 也叫Unicode编码 (Java内部机制就是处理Unicode值的) 举例:'a' 0x0061
* UTF-8编码 高8位是111打头的表示随后的三个字节凑在一起才是一个字符 例如中文
*           高8位是110打头的表示随后的两个字节凑在一起才是一个字符 例如脱离ISO8859-1范围的字符
*           高8位的首位是0的表示单字节的字符 例如ASCII范围内的字符
* UTF-32编码 每个字符都是硬性规定占4个字节
*/

/**
 * Java基本数据类型和byte数组相互转化的工具类
 *
 * 0xff 16进制表示法(每一个数字代表4bit) 32位在计算机内表示为 00000000 00000000 00000000 11111111 等于十进制的255
 *
 *  << 左移运算符:操作数向左移动N位(低位补0), 相当于操作数乘以2的几次方
 *  >> "有符号"右移运算符:操作数右移N位, 操作数为正时,高位补0 ; 操作数为正时,高位补1, 相当于操作数除以2的几次方
 * >>> "无符号"右移运算符:操作数右移N位(高位补0)
 *
 * 对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int(因为java的移位操作仅支持int位移 或者 long位移)
 *
 * 所以由此延申出的 byte的字节移位时,为什么要&0xff呢?其作用就是仅关心当前8bit这一字节,其它bit位都置为零,保持二进制补码的一致性;
 *
 * 举例:*				最高	 高	  稍高     最低
	255         0xff                00000000 00000000 00000000 11111111
        -1          (byte)0xff          11111111 11111111 11111111 11111111 
        1           0xff>>>7            00000000 00000000 00000000 00000001  >>>1111111
        33554431    ((byte)0xff)>>>7    00000000 00000001 11111111 11111111  >>>1111111
 *
 * &0xff 的作用:举例 int i = (byte)( -129 & 0xff );
 * -129 32位bit补码表示:原码:00000000 00000000 00000000 10000001 
 *                       求反:11111111 11111111 11111111 01111110  
 *                        加1:11111111 11111111 11111111 01111111 
 * 0xff 默认为int类型:         00000000 00000000 00000000 11111111
 * -129 & 0xff 的值为:        00000000 00000000 00000000 01111111
 * (byte)(-129&0xff)关心最低8位时:01111111
 * (byte)((-129>>8)&0xff)关心稍高8位时:11111111
 * 我们想把-129变成byte数组存储时,数组里面就是[11111111],[011111111]
 * 我们想把byte数组存储的转换为数值-129时,手法就是 short k = (byte[0]&0xff)<<8 | byte[1]&0xff 注意:移位操作java中仅支持int位移或long位移
 *
 * short k = (byte[0]&0xff)<<8 | byte[1]&0xff 的运算步骤
 *
 * byte[0]&0xff 运算:
 *                   第一步:byte[0]装入内存,高位补1, 机器内存中表示为:11111111 11111111 11111111 11111111
 *                           0xff装入内存,机器内存中表示为:           00000000 00000000 00000000 11111111
 *                           byte[0]&0xff的结果:                    00000000 00000000 00000000 11111111
 *
 *                   第二步:(byte[0]&0xff)<<8的结果:     00000000<< 00000000 00000000 11111111 00000000 最高位左移走,低位补0
 
 *                   第三步:byte[1]装入内存,高位补0, 机器内存中表示为:00000000 00000000 00000000 01111111
 *                           0xff装入内存,机器内存中表示为:           00000000 00000000 00000000 11111111
 *                           byte[1]&0xff的结果:                    00000000 00000000 00000000 01111111
 *
 *                   第四步:(byte[0]&0xff)<<8 | byte[1]&0xff 的运算:00000000 00000000 11111111 00000000
 *                                                                     |
 *                                                                   00000000 00000000 00000000 01111111
 *
 *                                                            结果为:00000000 00000000 11111111 01111111
 *
 *                   第五步:结果类型强转(int->short,丢弃最高,高):short k = -129; //也就是仅用稍高字节,最低字节 11111111 01111111       
 */

public class ByteUtil {

	/**
	* 得到基本类型的字节流
	* 泛型静态方法 public static <T> T xxMethod(T t){}
	*/
	public static <T> byte[] getBytes(T t){

		byte[] bytes = null ;

		if( (t instanceof Short)){

			short s = ((Short)t).shortValue();
			bytes = new byte[2];
			bytes[0] = (byte) (s);
			bytes[1] = (byte) (s>>8); 
		}
		else if(t instanceof Integer){

			int i = ((Integer)t).intValue();
			bytes = new byte[4];
			bytes[0] = (byte) (i);
			bytes[1] = (byte) (i>>8);
			bytes[2] = (byte) (i>>2*8);
			bytes[3] = (byte) (i>>3*8);			
		}
		else if(t instanceof Long){

			long l = ((Long)t).longValue();
			bytes = new byte[8];
			bytes[0] = (byte) (l);
			bytes[1] = (byte) (l>>8);
			bytes[2] = (byte) (l>>2*8);
			bytes[3] = (byte) (l>>3*8);
			bytes[4] = (byte) (l>>4*8);
			bytes[5] = (byte) (l>>5*8);
			bytes[6] = (byte) (l>>6*8);
			bytes[7] = (byte) (l>>7*8);
		}
		else if(t instanceof Float){

			int f = Float.floatToIntBits((Float)t);
			bytes = new byte[4];
			bytes[0] = (byte) (f);
			bytes[1] = (byte) (f>>8);
			bytes[2] = (byte) (f>>2*8);
			bytes[3] = (byte) (f>>3*8);			
		}
		else if(t instanceof Double){

			long d = Double.doubleToLongBits((Double)t);
			bytes = new byte[8];
			bytes[0] = (byte) (d);
			bytes[1] = (byte) (d>>8);
			bytes[2] = (byte) (d>>2*8);
			bytes[3] = (byte) (d>>3*8);
			bytes[4] = (byte) (d>>4*8);
			bytes[5] = (byte) (d>>5*8);
			bytes[6] = (byte) (d>>6*8);
			bytes[7] = (byte) (d>>7*8);
		}
		else if(t instanceof Character){
			char c = ((Character)t).charValue();
			bytes = new byte[2];
			bytes[0] = (byte) (c);
			bytes[1] = (byte) (c>>8); 
		}

		return bytes;
	}

	/**
	* 从字节流中获取基本类型的值
	*/
	public static <T> T getValue(byte[] bytes, Class<T> clazz ) {

		T rtnObj = null;

		if (clazz.equals(java.lang.Character.class)){

			rtnObj = (T)Character.valueOf((char)((bytes[1]&0xff) << 8 | (bytes[0]&0xff)));
		}
		else if (clazz.equals(java.lang.Short.class)){

			rtnObj = (T)(Short.valueOf((short)( (bytes[1]&0xff) << 8 | (bytes[0]&0xff) )));
		}
		else if (clazz.equals(java.lang.Integer.class)){

			rtnObj = (T)(Object)(  (bytes[3]&0xff) << 8*3 
								 | (bytes[2]&0xff) << 8*2
								 | (bytes[1]&0xff) << 8 
								 | (bytes[0]&0xff) 
				                );
		}
		else if (clazz.equals(java.lang.Long.class)){

			rtnObj = (T)(Object)(  (bytes[7]&0xffL) << 8*7 
								 | (bytes[6]&0xffL) << 8*6
								 | (bytes[5]&0xffL) << 8*5 
								 | (bytes[4]&0xffL) << 8*4
								 | (bytes[3]&0xffL) << 8*3 
								 | (bytes[2]&0xffL) << 8*2
								 | (bytes[1]&0xffL) << 8 
								 | (bytes[0]&0xffL) 
				                );
		}
		else if (clazz.equals(java.lang.Float.class)){

			int intBit = (  (bytes[3]&0xff) << 8*3 
						  | (bytes[2]&0xff) << 8*2
						  | (bytes[1]&0xff) << 8 
						  | (bytes[0]&0xff) 
						 );
			rtnObj = (T)(Object)Float.intBitsToFloat(intBit);
		}
		else if (clazz.equals(java.lang.Double.class)){

			long longBit = (   (bytes[7]&0xffL) << 8*7 
							 | (bytes[6]&0xffL) << 8*6
							 | (bytes[5]&0xffL) << 8*5 
							 | (bytes[4]&0xffL) << 8*4
							 | (bytes[3]&0xffL) << 8*3 
							 | (bytes[2]&0xffL) << 8*2
							 | (bytes[1]&0xffL) << 8 
							 | (bytes[0]&0xffL) 
							);
			rtnObj = (T)(Object)Double.longBitsToDouble(longBit);
		}		

		return rtnObj ;
	}


	public static void unicode(){
		String str1 = "中文测试";
		byte[] ch = new byte[100];
		try {
			ch = str1.getBytes("unicode");
			System.out.println(str1+" length:"+ch.length+" unicode: "+byte2hex(ch));
			ch = str1.getBytes("utf-16");
			System.out.println(str1+" length:"+ch.length+" utf-16: "+byte2hex(ch));
			//ch = str1.getBytes("UTF-16LE");
			//System.out.println(str1+" length:"+ch.length+" UTF-16LE: "+byte2hex(ch));
			//ch = str1.getBytes("UTF-16BE");
			//System.out.println(str1+" length:"+ch.length+" UTF-16BE: "+byte2hex(ch));
			ch = str1.getBytes("utf-8");
			System.out.println(str1+" length:"+ch.length+" utf-8: "+byte2hex(ch));
			ch = str1.getBytes("utf-32");
			System.out.println(str1+" length:"+ch.length+" utf-32: "+byte2hex(ch));
			
			str1 = "test";
			ch = str1.getBytes("unicode");
			System.out.println(str1+" length:"+ch.length+" unicode:"+byte2hex(ch));
			ch = str1.getBytes("utf-8");
			System.out.println(str1+" length:"+ch.length+" utf-8:"+byte2hex(ch));
			ch = str1.getBytes("utf-16");
			System.out.println(str1+" length:"+ch.length+" utf-16:"+byte2hex(ch));
			ch = str1.getBytes("utf-32");
			System.out.println(str1+" length:"+ch.length+" utf-32:"+byte2hex(ch));

			/**
			* 编码转换
			*/
			String str = "中国";
			String iso88591 = new String(str.getBytes("UTF-8"), "ISO-8859-1"); //中文GBK --> UTF-8 --> ISO-8859-1
			System.out.println(iso88591); //此时打印是6个问号,因为:一个中文UTF-8时是3个字节,两个中文就是6个字节,ISO又是单字节的字符
			str = new String(iso88591.getBytes("ISO-8859-1"), "UTF-8"); //返向的 ISO-8859-1 --> UTF-8 --> 中文GBK
			System.out.println(str);

			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String byte2hex( byte[] b) {     
	   StringBuilder s = new StringBuilder();
	   for (int i = 0; i < b.length; i++) {    
		 String hex = Integer.toHexString(b[i] & 0xFF);    
		 if (hex.length() == 1) {    
		   hex = '0' + hex;    
		 } 
		 s.append( hex.toUpperCase() );
	   }
	   return s.toString() ;
	}

	public static String bytesToHexString(byte[] src){   
		StringBuilder stringBuilder = new StringBuilder("");   
		if (src == null || src.length <= 0) {   
			return null;   
		}   
		for (int i = 0; i < src.length; i++) {   
			int v = src[i] & 0xFF;   
			String hv = Integer.toHexString(v);   
			if (hv.length() < 2) {   
				stringBuilder.append(0);   
			}   
			stringBuilder.append(hv);   
		}   
		return stringBuilder.toString();   
	}
	
	/**  
	 * Convert hex string to byte[]  
	 * @param hexString the hex string  
	 * @return byte[]  
	 */  
	public static byte[] hexStringToBytes(String hexString) {   
		if (hexString == null || hexString.equals("")) {   
			return null;   
		}   
		hexString = hexString.toUpperCase();   
		int length = hexString.length() / 2;   
		char[] hexChars = hexString.toCharArray();   
		byte[] d = new byte[length];   
		for (int i = 0; i < length; i++) {   
			int pos = i * 2;   
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));   
		}   
		return d;   
	}
	
	/**  
	 * Convert char to byte  
	 * @param c char  
	 * @return byte  
	 */  
	 private static byte charToByte(char c) {   
		return (byte) "0123456789ABCDEF".indexOf(c);   
	}  


	public static void main(String[] args) {

		char c = 'A';
		short s = -177 ;
		int i = -12345678;
		long l = -12345678900L;
		float f = -1234.567F;
		double d = -444444444.555555;

		System.out.println( getValue(getBytes(c), Character.class) );
		System.out.println( getValue(getBytes(s), Short.class) );
		System.out.println( getValue(getBytes(i), Integer.class) );
		System.out.println( getValue(getBytes(l), Long.class) );
		System.out.println( getValue(getBytes(f), Float.class) );
		System.out.printf("%f \r\n",getValue(getBytes(d),Double.class));	

		unicode();
	}
}

猜你喜欢

转载自blog.csdn.net/mmlz00/article/details/84974946