java开发规范(转载)
2017-02-12 23:54
253 查看
1.关于hashCode和equals的处理:
只要重写equals,就必须重写hashCode
因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法
如果自定义对象作为Map的键,那么必须重写hashCode和equals
2.ArrayList的subList结果不可强转成ArrayList,因为subList返回的是ArrayList的内部类SubList,并不是ArrayList,而是ArrayList的一个试图,对于SubList子列表的所有操作最终会反映到原列表上
3.使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()
直接使用toArray无参方法存在问题,此方法返回值只能是Object[]类,若强转其他类型数组将出现ClassCassException错误
4.使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,因为asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法,Arrays.asList体现的是适配器模式,只是转换接口,后天的数据仍是数组
5.不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁
6.使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历
keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是jdk8,使用Map.foreach方法
7.hashtable:key不允许为null,value不允许为null,线程安全;
ConcurrentHashMap:key不允许为null,value不允许为null,分段锁技术;
TreeMap:key不允许为null,value允许为null,线程不安全;
HashMap:key允许为null,value允许为null,线程不安全
8.线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式:
FixedThreadPool和SingleThreadPool:允许的请求队列长度为Integer.MAX_VALUE,可能会创建大量的请求,从而导致OOM
CachedThreadPool和ScheduledThreadPool:允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
9.SimpleDateFormat是线程不安全的类,一般不要定义为static遍历,如果为static,必须加锁
例子:
4000
同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁
11.对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁
12.多线程处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其他任务便会自动终止运行,使用ScheduledExcutorService则没有这个问题
13.使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至countDown方法,直到超时才返回结果(注:子线程抛出异常堆栈,不能在主线程try-catch到)
14.避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed导致的性能下降,在JDK7之后,可以直接使用ThreadLocalRandom
15.volatile解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但如果是多写,同样无法解决线程安全问题。如果是count++操作,使用如下类实现:
AtomicInteger count = new AtomicInteger();count.addAndGet(1);如果是jdk8,推荐使用LongAdder对象,比AtomicLong性能更好
16.HashMap在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升
17.在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。(不要在方法体内定义:Pattern pattern = Pattern.compile(规则))
18.任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存
19.不要捕获java类库中定义的继承自RuntimeException的运行时异常类,如:IndexOutOfBoundsException/NullPointerException,这类异常由程序员预检查来规避
20.应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
21.避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=false
22.可以使用warn日志级别来记录用户输入参数错误的情况,error级别只记录系统逻辑出错、异常等重要错误信息
23.hashtable(key不允许为null,value不允许为null,super为Dictionary,说明:线程安全)
concurrenthashmap(key不允许为null,value不允许为null,super为abstractmap,说明:分段锁技术)
treemap(不允许为null,允许为null,super为abstractmap,说明:线程不安全)
hashmap(允许为null,允许为null,super为abstractmap,说明:线程不安全)
只要重写equals,就必须重写hashCode
因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法
如果自定义对象作为Map的键,那么必须重写hashCode和equals
2.ArrayList的subList结果不可强转成ArrayList,因为subList返回的是ArrayList的内部类SubList,并不是ArrayList,而是ArrayList的一个试图,对于SubList子列表的所有操作最终会反映到原列表上
3.使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一样的数组,大小就是list.size()
直接使用toArray无参方法存在问题,此方法返回值只能是Object[]类,若强转其他类型数组将出现ClassCassException错误
4.使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,因为asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法,Arrays.asList体现的是适配器模式,只是转换接口,后天的数据仍是数组
5.不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁
6.使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历
keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是jdk8,使用Map.foreach方法
7.hashtable:key不允许为null,value不允许为null,线程安全;
ConcurrentHashMap:key不允许为null,value不允许为null,分段锁技术;
TreeMap:key不允许为null,value允许为null,线程不安全;
HashMap:key允许为null,value允许为null,线程不安全
8.线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式:
FixedThreadPool和SingleThreadPool:允许的请求队列长度为Integer.MAX_VALUE,可能会创建大量的请求,从而导致OOM
CachedThreadPool和ScheduledThreadPool:允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
9.SimpleDateFormat是线程不安全的类,一般不要定义为static遍历,如果为static,必须加锁
例子:
private static final ThreadLocal<DateFormate> df = new ThreadLocal<DateFormat>(){ @Override protected DateFormat initialValue(){ return new SimpleDateFormat("yyyy-MM-dd"); } }10.高并发时,
4000
同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁
11.对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁
12.多线程处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其他任务便会自动终止运行,使用ScheduledExcutorService则没有这个问题
13.使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法可以执行,避免主线程无法执行至countDown方法,直到超时才返回结果(注:子线程抛出异常堆栈,不能在主线程try-catch到)
14.避免Random实例被多线程使用,虽然共享该实例是线程安全的,但会因竞争同一seed导致的性能下降,在JDK7之后,可以直接使用ThreadLocalRandom
15.volatile解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但如果是多写,同样无法解决线程安全问题。如果是count++操作,使用如下类实现:
AtomicInteger count = new AtomicInteger();count.addAndGet(1);如果是jdk8,推荐使用LongAdder对象,比AtomicLong性能更好
16.HashMap在容量不够进行resize时由于高并发可能出现死链,导致CPU飙升
17.在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。(不要在方法体内定义:Pattern pattern = Pattern.compile(规则))
18.任何数据结构的构造或初始化,都应指定大小,避免数据结构无限增长吃光内存
19.不要捕获java类库中定义的继承自RuntimeException的运行时异常类,如:IndexOutOfBoundsException/NullPointerException,这类异常由程序员预检查来规避
20.应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
21.避免重复打印日志,浪费磁盘空间,务必在log4j.xml中设置additivity=false
22.可以使用warn日志级别来记录用户输入参数错误的情况,error级别只记录系统逻辑出错、异常等重要错误信息
23.hashtable(key不允许为null,value不允许为null,super为Dictionary,说明:线程安全)
concurrenthashmap(key不允许为null,value不允许为null,super为abstractmap,说明:分段锁技术)
treemap(不允许为null,允许为null,super为abstractmap,说明:线程不安全)
hashmap(允许为null,允许为null,super为abstractmap,说明:线程不安全)
相关文章推荐
- 阿里巴巴Java开发规范手册(转载)
- 【转载】JAVA 开发工具Jcreator使用技巧总结
- 设计迷踪:给JAVA设计开发新手的一些建议和意见(转载)
- 如何使用javadoc规范java开发文档
- 利用Java进行AcrSDE开发实例【转载】
- JAVA代码编程规范-Java基础-Java-编程开发
- 使用javadoc规范java开发文档
- 程序员注意:Java开发最容易犯的21种错误(转载)
- Java开发规范
- Jersey : Java规范下REST风格Web Service开发框架
- (转载)超越XML和JSON:YAML,Java开发人员的新选择
- 让PHP支持大型项目-构建JSP、PHP与JAVA融为一体的开发环境[转载]
- [转]使用javadoc规范java开发文档
- java开发代码规范
- JavaCard开发教程之规范
- [转载]让PHP支持大型项目-构建JSP、PHP与JAVA融为一体的开发环境
- 当前Java软件开发中几种认识误区(转载)
- 开发笔记:Java命名规范
- Java-开发命名规范
- (转载)Java开发最容易犯的几种错误