Effective Java之最佳建议

Effective Java之最佳建议

此书中,目前给我帮助最大的两条建议是:

  • 检查参数的有效性
  • 不要忽略异常

检查参数的有效性

对于这一条,使我感同身受的原因是:在Web项目中,前期经验不足,前台进行数据验证后,后端Java代码就没有进行任何验证就开始直接使用数据。这导致的后果当然是惨重的,其中细小的部分非常容易出bug。特别是设计到金钱交易的项目,闸门没有守好,则污水横流、危害系统。
所以当我看到这一条时,非常有感触。然而使我更加理解并决定坚决遵循这条规则的动力也在于作者一句定睛之语:

只要有效性检查有一次失败,你所付出的努力就可以连本带利得到偿还了

不要忽略异常

这条建议非常重要,奈何许多人都视而不见、常常违反。
一部分Java程序使用起来非常烦人,原因在于他出抛出大量的受检异常,try-catch块破坏了代码的美观和简洁。因此,省事儿的人在catch中习惯的一句写法就是:

e.printStackTrace();

这样的写法直接就忽略了异常,在下面的代码中,他们继续书写豪情,丝毫没有羞涩之感。
其实受检异常的存在,本身就表明情况是处于可恢复状态的,直接忽略他们是在不妥。但话说回来,如果对每个受检异常都进行特殊处理,那我们的工作量可就大了,如同插秧,对每个坏苗进行守护是不现实的,好的做法是直接剔除坏苗。
但程序和插秧还是有些区别的,在剔除坏苗的同时,你要让人知道哪里出了问题,否则错误的程序继续运行,如同危桥上的货车,迟早要出事儿。
一个好的解决方案是把受检异常变为运行时异常。

	public static RuntimeException unchecked(Exception e) {
		if (e instanceof RuntimeException) {
			return (RuntimeException) e;
		} else {
			return new RuntimeException(e);
		}
	}

但这样对于原有的程序简洁性还是没有什么提升,try-catch块还是如此碍眼。拿Java反射来说,几乎处处都是受检异常(简单起见,没有对受检异常进行处理):

	Class cl = City.class;
        City city = null;
        try {
            city = cl.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        Method method = null;
        try {
            method = cl.getMethod("getName", null);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            Object obj = method.invoke(city, null);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

使用起来,确实让人头大。当然,我们可以放在一个try-catch块中指定,不过也不美观。
我想到的解决方法是对常用的反射方法进行封装,去除掉这些异常:

    public static T getInstance(Class cl) {
        try {
            return cl.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        throw new RuntimeException();
    }

    public static Method getMethod(Class<?> cl, String methodName,Class<?>... parameterTypes) {
        try {
            return cl.getMethod(methodName, parameterTypes);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        throw new RuntimeException();
    }

    public static Object invoke(Method method, Object obj,Object... args) {
        try {
            return method.invoke(obj, args);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        throw new RuntimeException();
    }

这样在使用的时候,可以直接调用这些工具方法即可。
Effective中还有很多具有建设性的意见,就不一一列举了,感兴趣的人可买一本书来参考。

posted @ 2014-02-19 16:10  轩辕李  阅读(499)  评论(2编辑  收藏  举报