一个死循环导致的栈溢出实例:StackOverFlowError
有一个功能,要用复选框组做成单选框效果,如果有三个复选框 CheckBox ,并且保证每次只能选中一个。刚开始添加了以下的值改变后的监听方法 addValueChangeListener ,却导致了栈溢出:
public static void checkBoxAddChangeListener(CheckBox checkBox1, CheckBox checkBox2, CheckBox checkBox3){
checkBox1.addValueChangeListener(e -> {
checkBox2.setValue(!checkBox1.getValue());
checkBox3.setValue(!checkBox1.getValue());
});
checkBox2.addValueChangeListener(e -> {
checkBox1.setValue(!checkBox2.getValue());
checkBox3.setValue(!checkBox2.getValue());
});
checkBox3.addValueChangeListener(e -> {
checkBox1.setValue(!checkBox3.getValue());
checkBox2.setValue(!checkBox3.getValue());
});
}
思考上面代码的逻辑,假如现在第二个复选框是选中状态,此时再选中了第一个复选框,会触发第一个复选框的监听事件,第二、三个复选按钮就变成了未选中状态。因为第二个复选框的状态改变了,会触发它的监听事件,此时第一、三个复选框会变成选中状态。因为第一个已经是选中状态了,所以不会触发值改变的监听器。但是第三个复选框的状态却变了,触发监听器事件,把第一、二个监听器变成未选中状态。此时会再次触发第一个复选框的监听器事件。如此往复循环,StackOverFlowError
正确做法之一就是,不要在值改变的时候就触发事件,要在复选框的值变成选中状态时,触发一次事件就好了。添加以下判断。
public static void checkBoxAddChangeListener(CheckBox checkBox1, CheckBox checkBox2, CheckBox checkBox3){
checkBox1.addValueChangeListener(e -> {
if(checkBox1.getValue()){
checkBox2.setValue(false);
checkBox3.setValue(false);
}
});
checkBox2.addValueChangeListener(e -> {
if(checkBox2.getValue()){
checkBox1.setValue(false);
checkBox3.setValue(false);
}
});
checkBox3.addValueChangeListener(e -> {
if(checkBox3.getValue()){
checkBox1.setValue(false);
checkBox2.setValue(false);
}
});
}
这段代码还可以优化成一组复选框里只能选中一个值的方法,如下:
public static void checkBoxAddChangeListener(List<CheckBox> list){
for(int i=0; i<list.size(); i++){
CheckBox checkBox = list.get(i);
checkBox.addValueChangeListener(e -> {
if(checkBox.getValue()){
for (CheckBox tmp : list) {
if (tmp == checkBox) {
continue;
}
tmp.setValue(false);
}
}
});
}
}
附录:
但是最开始的错误方法,如果只有两个CheckBox,就不会报错了
public static void checkBoxAddChangeListener(CheckBox checkBox1, CheckBox checkBox2){
checkBox1.addValueChangeListener(e -> {
checkBox2.setValue(!checkBox1.getValue());
});
checkBox2.addValueChangeListener(e -> {
checkBox1.setValue(!checkBox2.getValue());
});
}
原因是:这两个监听器,每一个只能触发一个。
假如开始第二个复选框是选中状态,此时选中第一个复选框,触发第一个复选框的监听事件,把第二个复选框变成未选中状态。再触发第二个复选框的监听事件,此时把第一个复选框变成了选中状态。但是因为第一个复选框本身已经是选中状态了,所以它的值并没有改变,所以不会触发监听器事件。
原创文章,欢迎转载,转载请注明出处!
一个死循环导致的栈溢出实例:StackOverFlowError的更多相关文章
- linux 内核假死循环导致的问题
[, comm: -IFileSender Tainted: G B ENX -- ZTE Grantley/S1008 [:[<ffffffff810fb2cb>] [<fffff ...
- PureMVC和Unity3D的UGUI制作一个简单的员工管理系统实例
前言: 1.关于PureMVC: MVC框架在很多项目当中拥有广泛的应用,很多时候做项目前人开坑开了一半就消失了,后人为了填补各种的坑就遭殃的不得了.嘛,程序猿大家都不喜欢像文案策划一样组织文字写东西 ...
- 一个简单的Android小实例
原文:一个简单的Android小实例 一.配置环境 1.下载intellij idea15 2.安装Android SDK,通过Android SDK管理器安装或卸载Android平台 3.安装J ...
- 初学redux笔记,及一个最简单的redux实例
categories: 笔记 tags: react redux 前端框架 把初学redux的一些笔记写了下来 分享一个入学redux很合适的demo, 用redux实现计数器 这是从阮一峰老师git ...
- 一个简单的jQuery插件开发实例
两年前写的一个简单的jQuery插件开发实例,还是可以看看的: <script type="text/javascript" src="jquery-1.7.2.m ...
- [WCF REST] 一个简单的REST服务实例
Get:http://www.cnblogs.com/artech/archive/2012/02/04/wcf-rest-sample.html [01] 一个简单的REST服务实例 [02] We ...
- 10-多写一个@Autowired导致程序崩了
再是javaweb实验六中,是让我们改代码,让它跑起来,结果我少注释了一个,导致一直报错,检查许久没有找到,最后通过代码替换逐步查找,才发现问题.
- this.$Message.success('提示信息') 少写了一个c 导致报错
this.$Message.success('提示信息') 少写了一个c 导致报错 而且 $Message 输出还没显示,导致我以为是没有 $Message 对象了,其实全局对象直接调用即可
- 如何将RAC数据库的 RMAN Disk 备份 Restore 到另一个节点上的单个实例 (Doc ID 415579.1)
HowTo Restore RMAN Disk backups of RAC Database to Single Instance On Another Node (Doc ID 415579.1) ...
随机推荐
- 2-微信小程序开发(开发界面说明,按钮点击切换显示内容)
说一个功能,大家在用微信实现控制设备的时候,是不是都在为绑定设备发愁. 我看了很多厂家的微信控制,大部分都只是可以用微信给设备配网,但是没有做用微信绑定的. 一般做绑定都是用设备的MAC地址. 这里我 ...
- 加解密工具类(含keystore导出pfx)
java代码如下: package sign; import java.io.FileInputStream; import java.io.FileOutputStream; import java ...
- 欧拉函数(小于或等于n的数中与n互质的数的数目)&& 欧拉函数线性筛法
[欧拉函数] 在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler’s totient function.φ函数.欧拉商数等. 例如φ( ...
- PHP从入门到精通(六)
PHP中的错误处理 1.PHP的错误级别:见表格.2.调整PHP错误报告级别:PHP中,调整错误报告级别的方式有两种: ①修改PHP.ini文件的配置项.a.会导致在当前服务器环境下所有PHP文件都受 ...
- 基于Python的ModbusTCP客户端实现
Modbus协议是由Modicon公司(现在的施耐德电气Schneider Electric)推出,主要建立在物理串口.以太网TCP/IP层之上,目前已经成为工业领域通信协议的业界标准,广泛应用在工业 ...
- c++入门之关于cin,cout以及数据流的认识
- Pair Project1:电梯控制程序
12061199 程刚 && 12061204 黎柱金 一.结对编程的优缺点 结对编程相对于一个人的编程有更多的优点,缺点也有很大不同. 首先,优点: 结队可以让两人可以更好的协 ...
- net license tool, EasyLicense !
net license tool, EasyLicense ! 开源 .net license tool, EasyLicense ! 介绍: 过去我常常像是否有一个帮助授权的软件,它可以非常简单 ...
- Centos wget命令 not found解决方法
如果已经有了yun源,则可通过yun源命令来安装wget. 如下所示: 2.yum安装yum -y install wget 即可安装:
- octave基本指令3
octave基本指令3 数据运算 >> a = [1 2; 3 4; 5 6]; >> b = [11 12; 13 14; 15 16]; >> c = [1 1 ...