重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
举个例子,PHP设置报错级别(来源PHP官网示例:https://www.php.net/manual/zh/function.error-reporting.php):
创新互联专注于中大型企业的网站制作、成都网站制作和网站改版、网站营销服务,追求商业策划与数据分析、创意艺术与技术开发的融合,累计客户上千多家,服务满意度达97%。帮助广大客户顺利对接上互联网浪潮,准确优选出符合自己需要的互联网运用,我们将一直专注品牌网站建设和互联网程序开发,在前进的路上,与客户一起成长! 1
可以看到我们设置错误级别非常方便,想要哪些错误级别直接用 “|” 链接即可;
Java中网络编程,使用的 java.nio.channels.SelectionKey 中设置 Interest Option 也是类似操作:
tmpKey.interestOps(tmpKey.interestOps() | SelectionKey.OP_READ);
打开 java.nio.channels.SelectionKey 源码发现定义了
OP_READ = 1
OP_WRITE = 4
OP_CONNECT = 8
……
等类常量;
再向下翻,发现一段代码:
public final boolean isReadable() {
return (this.readyOps() & 1) != 0;
}
原来前面通过设置interestOps后,判断channel是否可读就是判断:(this.readyOps() & 1) != 0;
原理也很简单,二进制操作 | 相当于加,即对应的二进制位变更为1,&操作即为 判断是否有相同位置均为1;
例如:
1 | 2 得 3,
1二进制 0001
2 二进制 0010
或之后,只要对应位置任意一位为 1, 即将该位置变更为1;
3 二进制 0011
得到3后,判断用户是否设置了 常量值为1对应的选项,即为:
3 & 1
3 二进制 0011
1 二进制 0001
与之后,对应位置均为1得1否则得0:
0001 十进制(1), 1!= 0 成立,返回true,说明用户设置了 常量值为1对应的选项!
那么如何选择 选项常量值呢?可以看到Java SelectionKey 设置的是依次是 1、4、 8 ...
实际上因为十进制数二进制或操作可以看做是 两个数之间 的加和!
如 1 | 2 == 3, 2 | 4 == 6
所以选取选项的值,原则遵循 下一个选项值比前面所有选项值加和大即可;
例如可以这样设计:
0 E_NONE 1 E_NOTICE 2 E_WARN 4 E_ERROR 8 E_ALL0 < 1
0 + 1 < 2;
0 + 1 + 2 = 3 < 4
0 + 1 + 2 + 4 = 7 < 8
以此类推
设置选项时,比如想要E_ALL登记,却要排除E_NOTICE, 直接 E_ALL & ~E_NOTICE 即可!
用Java编写一个简单的错误信息上报功能组件:
1 public class ReportLevel {
2 public static final int E_NONE = 0;
3 public static final int E_NOTICE = 1;
4 public static final int E_WARNING = 2;
5 public static final int E_ERROR = 4;
6
7 // all notice/warning/error exception or error 8 public static final int E_ALL = 7;
9
10 public static int REPORT_LEVEL;
11
12 public static void setReportLevel(int reportLevel) {
13 REPORT_LEVEL = reportLevel;
14 }
15
16 public static boolean shouldReportNotice() {
17 return (REPORT_LEVEL & E_NOTICE) != 0;
18 }
19
20 public static boolean shouldReportWarning() {
21 return (REPORT_LEVEL & E_WARNING) != 0;
22 }
23
24 public static boolean shouldReportError() {
25 return (REPORT_LEVEL & E_ERROR) != 0;
26 }
27 }
测试使用:
1 public class ReportLevelTest {
2
3 @Test
4 public void testAddLevel() {
5 ReportLevel.setReportLevel(ReportLevel.E_WARNING | ReportLevel.E_ERROR);
6
7 Assert.assertTrue(ReportLevel.shouldReportWarning());
8 Assert.assertTrue(ReportLevel.shouldReportError());
9
10 Assert.assertFalse(ReportLevel.shouldReportNotice());
11 }
12
13 @Test
14 public void testExcludeLevel() {
15 // 写为 ReportLevel.E_ALL ^ ReportLevel.E_NOTICE 也可以
16 // ReportLevel.setReportLevel(ReportLevel.E_ALL & ~ReportLevel.E_NOTICE);17 ReportLevel.setReportLevel(ReportLevel.E_ALL ^ ReportLevel.E_NOTICE);
18
19 Assert.assertTrue(ReportLevel.shouldReportWarning());
20 Assert.assertTrue(ReportLevel.shouldReportError());
21
22 Assert.assertFalse(ReportLevel.shouldReportNotice());
23 }
24
25 @Test
26 public void testNone() {
27 ReportLevel.setReportLevel(ReportLevel.E_NONE);
28
29 Assert.assertFalse(ReportLevel.shouldReportWarning());
30 Assert.assertFalse(ReportLevel.shouldReportError());
31 Assert.assertFalse(ReportLevel.shouldReportNotice());
32 }
33 }