Java位操作与数据类型转换全解析
立即解锁
发布时间: 2025-08-18 02:21:30 阅读量: 2 订阅数: 12 

# Java 位操作与数据类型转换全解析
## 1. 位掩码常量
在 Java 中,有一些常量用于计算位掩码,例如:
```java
private static final int FOCUS_INPUTMAP_CREATED = 7;
private static final int ANCESTOR_INPUTMAP_CREATED = 8;
private static final int WIF_INPUTMAP_CREATED = 9;
private static final int ACTIONMAP_CREATED = 10;
private static final int CREATED_DOUBLE_BUFFER = 11;
private static final int IS_PRINTING = 12;
private static final int IS_PRINTING_ALL = 13;
```
这些常量并非实际的位掩码,而是计算位掩码值所需的移位距离。这种位处理方式的代码效率略低于传统位处理,因为存在额外的方法调用和掩码值的不断重新计算。但其主要优点是可读性高,不过性能的些许下降以及一次只能设置或清除一位的限制,使其难以成为编程惯例。
## 2. 半字节转换为十六进制数字
### 2.1 半字节概念
半字节(nybble)是介于位和字节之间的概念,它由四个位组成,可以转换为十六进制数字(0 - 9 和 a - f 或 A - F)。在核心 API 中,`Integer.toHexString(int i)` 和 `Long.toHexString(long i)` 方法实现了半字节到十六进制数字的转换。
### 2.2 转换方法示例
```java
static char[] hexDigits = {'0','1','2','3','4',
'5','6','7','8','9',
'a','b','c','d','e','f'};
static String toHexString(int i) {
char[] buf = new char[8];
int index = 8;
do {
buf[--index] = hexDigits[i & 0xF];
i >>>= 4;
} while (i != 0);
return new String(buf, index, 8 - index);
}
```
此方法使用 `do` 循环确保零返回 `"0"`,并从右到左处理半字节。
### 2.3 优化策略
多数十六进制转换方法有以下常见优化:
- **避免调用 `Character.forDigit` 方法**:该方法开销大,包含方法调用和参数检查。
```java
final static char[] chars = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};
public static char forDigit(int digit, int radix) {
if ((digit >= radix) || (digit < 0)) {
return '\0';
}
if ((radix < MIN_RADIX) || (radix > MAX_RADIX)) {
return '\0';
}
return chars[digit];
}
```
- **使用 `char[]` 缓冲区**:避免使用 `StringBuffer`,因为其速度较慢。
- **使用静态 `hexDigits` 数组**:避免每次转换都分配和加载数组。
### 2.4 右移运算符的使用
在实际应用中,有符号和无符号右移运算符常可互换使用,作为位处理的“传送带”。例如:
```java
class Test {
static char[] hexDigits = {'0','1','2','3','4',
'5','6','7','8','9',
'a','b','c','d','e','f'};
public static void main(String[] args) {
toHexString(1234567890); // 0x499602d2
}
static void toHexString(int i) {
do {
String s = BitPattern.toBinaryString(i);
System.out.println(s);
System.out.println(s.substring(31, 35) + " = 0x" +
hexDigits[i & 0xF]);
i >>>= 4;
System.out.println();
} while (i != 0);
}
}
```
执行该程序可看到“传送带”的工作原理,每次迭代掩码低四位并转换为十六进制数字。
### 2.5 替代方法
除了使用 `hexDigits` 数组,还可使用半字节的数值作为偏移量:
```java
do {
int offset = i & 0xF; //value of the nybble
char digit = (char)((offset < 10) ?
('0' + offset) : ('a' + offset - 10));
} while ((i >>>= 4) > 0);
```
实际微基准测试表明,数组访问表达式略快。
### 2.6 处理负数的方法
```java
static String toHexString(int i) {
char[] string = new char[9];
int index = 9;
if (i == Integer.MIN_VALUE) { //otherwise i = -i is a bug
return "-2147483648";
}
boolean negative = i < 0;
if (negative) {
i = -i;
}
do {
string[--index] = hexDigits[i & 0xF];
i >>>= 4;
} while (i != 0);
if (negative) {
string[--index] = '-';
}
return new String(string, index , (9 - index));
}
```
此方法处理负数时使用负号而非转换符号位。
## 3. 通用整数到字符串的转换方法
### 3.1 两种转换技术
整数到字符串的转换主要有两种编程技术:
- **适用于二进制、八进制和十六进制的方法**:使用右移运算符作为“传送带”并掩码低阶位。
- **适用于十进制和通用转换的方法**:该方法用于将整数转换为十进制数字,因为十进制数字与固定位数不对应,需要使用除以基数的方法。
### 3.2 除法作为“传送带”
```java
class Test {
public static void main(String[] args) {
int i = 123456789;
System.out.println(i);
while (i != 0)
System.out.println(i /= 10);
}
}
```
执行该程序可看到除以基数有效截断最右侧数字,余数即为最右侧数字的值。
### 3.3 转换示例
```java
static char[] digits = {'0','1','2','3','4',
'5','6','7','8','9'};
static String toString(int i) {
char[] string = new char[11];
int index = 11;
if (i == Integer.MIN_VALUE) { //otherwise i = -i is a bug
return "-2147483648";
}
boolean negative = i < 0;
if (negative) {
i = -i;
}
do {
string[--index] = digits[i%10];
i = i / 10;
} while (i != 0);
if (negative) {
string[--index] = '-';
}
return new String(string, index , (11 - index));
}
```
### 3.4 核心 API 中的应用
在核心 API 中,`Integer.toString(int i, int radix)` 和 `Long.toString(long i, int radix)` 方法使用了上述编程技术。但从 1.4 版本开始,`Integer.toString(int i)` 方法采用了不同实现,使用“不变乘法除法”避免了除以 10 的操作。
## 4. 无符号字节的处理
### 4.1 有符号与无符号字节的区别
Java 中的 `byte` 数据类型是有符号的,范围为 -128 到 127,而通常所说的字节指无符号字节,范围为 0 到 255。
```java
class Test {
public static void main(String[] args) {
byte b = (byte) 255;
System.out.println("signed byte = " + b);
System.out.println("unsigned byte = " + (
```
0
0
复制全文
相关推荐









