你的程序够健壮么?我看未必。。。

问题引出:

        从刚接触代码就被灌输这样的思想:

        1. 你写的代码不是没有错误,而是至今还没有发现错误。

        2. 测试是为了发现错误,而不是为了确定软件没有错误。

        3. 写的代码一定要有很高的健壮性。

        但是,你看一下下面的代码,你觉得这个代码的健壮性如何?

public class Test{
	public static void main(String[] args) throws InterruptedException{
		final int[] denominators={1,2,3};
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Divide100By(denominators);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
		Thread.sleep(50);
		denominators[2]=0;
		
	}
	private static void Divide100By(Object o) throws InterruptedException{
		int[] denominators=(int[]) o;
		for(int i=0;i<denominators.length;i++){
			if(denominators[i]==0){
				throw new RuntimeException("除数不能为0");
			}
		}
		System.out.println("所有的除数都合法");
		Thread.sleep(100);
		for(int i=0;i<denominators.length;i++){
			//System.out.println(""+denominators[i]);
			System.out.println("100/"+denominators[i]+"="+100/denominators[i]);
		}
	}
}

问题分析

        依我看,上面的Divide100这个方法,是一个不错的代码,因为他对传过来的数组进行了是否为0的判断。
        在这里引入一条:对方法的参数,需要进行有效性判断。因为方法执行正确比方法执行错误的执行效率要高很多
        而在我执行上面代码的时候,却意外的发现有错。这是怎么回事呢?
        原来在传递参数的时候,如果是值类型,会采取传值的方式进行传递,如果是对象,那么就会传引用。关于传值和传引用的具体区别,大家可以看一下这篇博客:http://blog.csdn.net/hanxuemin12345/article/details/10470955
        大概意思就是传引用形参和实参会相互影响,传值互不影响。
        正是由于这点的存在,让这个看似健壮的方法产生了错误。

问题总结

        解决方法其实很简单,在将形参转型后,再声明一个一模一样的数组,然后把转好的数组复制给新的数组,剩下的所有操作都对这个新数组操作就可以摆脱这个问题了。
        其实如果不是要写成一个类库,如果不采用多线程,如果你不知道传引用和传值的区别,一切都没那么麻烦。但我们要做的不是这样的人。
        通过这个例子,又一次体会了“不是没有错,而是暂时还没有发现错”这句话。也希望大家受到这个的启发,在开发的时候,尽量使自己写的代码能够正确被调用。
原文地址:https://www.cnblogs.com/pangblog/p/3304018.html