平常都很少用到位运算,这里介绍一种jdk使用位运算的小案例。它是用位运算来优化一个类所占的大小。下面介绍:
- 什么情况下,符合这种优化条件;
 
- 用具体的例子来介绍;
 
优化情况
假设一个类需要有很多boolean类型得属性,如果直接用boolean类型,那么这个类会在内存中占用很大空间。通常情况下,一个boolean类型属性会占4个字节。但这不是一定得,JAVA得boolean属性占用字节不一定。这时候,使用多个boolean类型的属性就占用很多内存。
在这种情况下,可以使用字节得0、1来代表true、false。使用位运算来获取、设置boolean属性得值。比如说:我们可以使用int来存储32个boolean属性,这样就会节省大量的内存。
JDK中有具体得例子,如java.lang.reflect.Modifier 
具体例子
假设一个猫有三个属性:cute、fat、white,其取值只有俩种true、false。现在用int的后面三个位来存储这三个类型的值。
即:在int最后一个位作为cute属性得值;倒数第二位作为fat属性得值;倒数第三位作为white属性得值。
1、创建int属性得值,作为存储这三个属性得属性值
1 2 3 4
   | public class Cat {          private int properties = 0; }
  | 
 

2、设置三个int属性作为三个属性都为true;这是为了后期方便设置值
1 2 3 4 5 6
   | public class Cat {     private static int CUTE = 0x1;     private static int FAT = 0x2;     private static int WHITE = 0x4;     private int properties = 0; }
  | 
 
3、以cute属性的获取、设置
(1)获取值的时候
指获取properties属性的最后一位的值,需要注意的是获取最后一位值得时候,不能影响其他位得值!!!
1 2 3 4 5 6 7 8
   | 
 
 
 
  public boolean isCute() {     return (properties & Cat.CUTE) != 0; }
 
  | 
 
使用与运算得时候,其他位不受影响;最后一位也是取决于properties最后一位得值

(2)设置值的时候
在设置properties属性得最后一位得值,需要注意得是设置最后一位的值的时候,不能影响其他位得值!!!
1 2 3 4 5 6 7 8 9 10 11 12
   | 
 
 
 
  public void setCute(boolean cute) {     if (cute == true){         properties = properties | Cat.CUTE;     } else {         properties = properties & (~Cat.CUTE);     } }
 
  | 
 

4、设置其他属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
   | 
 
 
 
  public void setFat(boolean fat) {     if (fat){         properties = properties | Cat.FAT;     } else {         properties = properties & (~Cat.FAT);     } }
 
 
 
 
 
  public boolean isFat() {     return (properties & Cat.FAT) != 0; }
 
 
 
 
 
  public void setWhite(boolean white) {     if (white){         properties = properties | Cat.WHITE;     } else {         properties = properties & (~Cat.WHITE);     } }
 
 
 
 
 
  public boolean isWhite() {     return (properties & Cat.WHITE) != 0; }
 
  | 
 
总结
一般情况下,获取值使用&;设置值使用|、~和&。关键就是在使用位运算的时候,只影响指定位置的值,其他位置的值不能改变。完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
   | public class Cat {     private static int CUTE = 0x1;     private static int FAT = 0x2;     private static int WHITE = 0x4;     private int properties = 0;
      
 
 
 
      public void setCute(boolean cute) {         if (cute == true){             properties = properties | Cat.CUTE;         } else {             properties = properties & (~Cat.CUTE);         }     }
      
 
 
 
      public boolean isCute() {         return (properties & Cat.CUTE) != 0;     }
      
 
 
 
      public void setFat(boolean fat) {         if (fat){             properties = properties | Cat.FAT;         } else {             properties = properties & (~Cat.FAT);         }     }
      
 
 
 
      public boolean isFat() {         return (properties & Cat.FAT) != 0;     }
      
 
 
 
      public void setWhite(boolean white) {         if (white){             properties = properties | Cat.WHITE;         } else {             properties = properties & (~Cat.WHITE);         }     }
      
 
 
 
      public boolean isWhite() {         return (properties & Cat.WHITE) != 0;     }
      public static void main(String[] args) {         Cat cat = new Cat();         cat.setCute(true);         cat.setFat(true);         cat.setWhite(false);         System.out.println("这只猫萌吗:" + cat.isCute());         System.out.println("这只猫胖吗:" + cat.isFat());         System.out.println("这只猫白吗:" + cat.isWhite());     } }
  | 
 
位运算的一些坑
交换俩个值得功能可以用位运算这种骚操作完成。比如:
1 2 3 4 5 6 7 8 9 10 11 12
   | public static void main(String[] args) {     Main main = new Main();     int[] arr = {1,2};     main.test(0,1,arr); }
  public void test(int a, int b, int[] arr){     arr[a] = arr[a] ^ arr[b];     arr[b] = arr[a] ^ arr[b];     arr[a] = arr[a] ^ arr[b];     System.out.println(Arrays.toString(arr)); }
  | 
 
但这里有个坑,如果你传得俩个地址是一样得话,就会出错:
1 2 3 4 5 6 7 8 9 10 11 12
   | public static void main(String[] args) {     Main main = new Main();     int[] arr = {1,2};     main.test(0,0,arr); }
  public void test(int a, int b, int[] arr){     arr[a] = arr[a] ^ arr[b];     arr[b] = arr[a] ^ arr[b];     arr[a] = arr[a] ^ arr[b];     System.out.println(Arrays.toString(arr)); }
  |