系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、捕获不可能出现的异常
- 二、transient的误用
- 三、不必要的初始化
- 四、最好用静态final定义Log变量
- 五、选择错误的类加载器
前言
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。
一、捕获不可能出现的异常
错误的写法:
try {
... do risky stuff ...
} catch(SomeException e) {
// never happens
}
... do some more ...
正确的写法:
try {
... do risky stuff ...
} catch(SomeException e) {
// never happens hopefully
throw new IllegalStateException(e.getMessage(), e); // crash early, passing all information
}
... do some more ...
二、transient的误用
错误的写法:
public class A implements Serializable {
private String someState;
private transient Log log = LogFactory.getLog(getClass()); public void f() {
log.debug("enter f");
...
}
}
这里的本意是不希望Log对象被序列化. 不过这里在反序列化时, 会因为log未初始化, 导致f()方法抛空指针, 正确的做法是将log定义为静态变量或者定位为具备变量。
正确的写法:
public class A implements Serializable {
private String someState;
private static final Log log = LogFactory.getLog(A.class); public void f() {
log.debug("enter f");
...
}
}
public class A implements Serializable {
private String someState; public void f() {
Log log = LogFactory.getLog(getClass());
log.debug("enter f");
...
}
}
三、不必要的初始化
错误的写法:
public class B {
private int count = 0;
private String name = null;
private boolean important = false;
}
这里的变量会在初始化时使用默认值:0, null, false, 因此上面的写法有些多此一举。
正确的写法:
public class B {
private int count;
private String name;
private boolean important;
}
四、最好用静态final定义Log变量
private static final Log log = LogFactory.getLog(MyClass.class);
这样做的好处有三:
可以保证线程安全
静态或非静态代码都可用
不会影响对象序列化
五、选择错误的类加载器
错误的代码:
Class clazz = Class.forName(name);
Class clazz = getClass().getClassLoader().loadClass(name);
这里本意是希望用当前类来加载希望的对象, 但是这里的getClass()可能抛出异常, 特别在一些受管理的环境中, 比如应用服务器, web容器, Java WebStart环境中, 最好的做法是使用当前应用上下文的类加载器来加载。
正确的写法:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) cl = MyClass.class.getClassLoader(); // fallback
Class clazz = cl.loadClass(name);