Java开发小tip(持续更新) 一些好用的类;一些需要注意的地方等等。

  • Java8下并发计数可以使用LongAdder替代之前的AtomicLong, 由于减弱了高并发下可能出现的循环重试死锁,前者效率、性能都更高。(拓展阅读:比AtomicLong还高效的LongAdder 源码解析

  • 大量重复字符串操作时,可以使用String的intern()方法将字符串放入Java的常量池中,如果下一次使用到的字符串在池中有命中,那么不会再重新创建对象,而是直接保存对象的引用。以此可以节省空间,但会消耗性能。(关于intern方法详解参考:美团技术博客

  • Lombok,通过注释为类自动生成Getter/Setter、toString等方法,简洁代码的工具包。

  • 对于数据库大数据集的分批处理,可以使用JDBC的setFetchSize方法,ResultSet读取的并不是当前数据库的数据,而是数据库维护的当前查询结果的缓存,而setFetchSize则是限制ResultSet每次从缓存中读取的数量,这样既不需要在代码中分页分批查询处理,又防止了一次性查询数据过多导致内存溢出。

  • Word中文分词插件。(Github:Java分布式中文分词组件 - word分词

  • fasterxml.jackson提供了@JsonProperty注解,添加在类的属性上,在类实例序列化和反序列化时,可以把该属性的实际名称映射为注解中标注的名称。如下图,在序列化该属性时,接收方就可以用displayName去接收。

    1. @JsonProperty("displayName")
    2. private String trueName;

Sonar中提示的开发过程中没有发现的错误

  • Marking a non-public method @Transactional is both useless and misleading because Spring doesn’t “see” non-public methods, and so makes no provision for their proper invocation. Nor does Spring make provision for the methods invoked by the method it called.

    Fixed:Spring的@Transactional注解只对public方法生效,Spring在扫描时会忽略非public方法

  • Loggers should be used instead to print throwables.

    Fixed:类似e.printStackTrace()这种控制台打印只能用于开发调试阶段,生产环境中应当删掉而使用Logger打印日志,如Log4j等

  • Move the “” string literal on the left side of this string comparison.

    Fixed:判断字符串是否为某个值时,应当将比较的常量放在equals左侧;同理,比较对象是否为null时也是。

  • Using classes and methods that rely on the default system encoding can result in code that works fine in its “home” environment.

    Fixed:对于文件、数据流、编码等操作,如String.getBytes、new InputStreamReader等,尽量不要使用默认的无参构造方法,即不要使用String.getBytes(),而是使用String.getBytes(Charset.forName(“UTF-8”))。编码默认是根据项目创建时的编码进行操作的,显式指定编码类型更容易排错。

Spring相关

  • 使用JPA、Hibernate等框架在进行数量相关的查询时,报 java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer

    Hibernate 3.2之后,sql函数如count()、sum()等的唯一返回值已经从Integer变为Long

  • JPA中如何查询自定义对象(即查询结果非DB Modal)?

    例:@Query(select new com.xx.yy.PersonResult(p.id as personId,p.name,p.age) from Person p),使用构造函数方式,查询结果自动转换为对应的Modal